I have a rails app in which I have a function that send out quite a few emails. I would like to do it asynchronously
and I thought that the method deliver_later
would do that. Currently I have some delay from when the user clicks submit
until the form is submitted - which is leads to a bad user experience (It is a quite simple form). My implementation looks like this:
def create
respond_to do |format|
if @competition.save
[...]
send_notification_to_team_members
end
end
def send_notification_to_team_members
@team.members.each do |member|
unless member.user.eql?(current_user)
Mailer.deliver_new_competition_notification(member.user, @competition).deliver_later
end
end
end
Currently it takes ~ 4 seconds for the action to be finished. I have also tried:
Mailer.deliver_new_competition_notification(member.user, @competition).deliver_later(wait: 1.minute)
Then it takes even longer - I would estimate ~1 minute.
So, am I using deliver_later
wrongly, or is the method not doing what I expect. In that case, is there another method I can use to improve my performance?
deliver_later
uses ActiveJob to provide asynchronous execution.
However ActiveJob does not provide asynchronicity itself - it is a unifying api layer that can be fulfilled by many backends. The default one just runs everything inline it is not async.
To get async usage you need to pick an asynchronous backend. You can configure the backend in your application's config
config.active_job.queue_adapter = ...
In general most adapters require a corresponding gem (eg delayed_job, sidekiq, sucker_punch) which may have their own dependencies too (for example sidekiq requires that you use redis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With