In the wiki I see the following examples:
From Getting started:
Send a message to be processed asynchronously:
HardWorker.perform_async('bob', 5)You can also send messages by calling the delay method on a class method:
User.delay.do_some_stuff(current_user.id, 20)
Also, from Delayed extensions:
Use delay to deliver your emails asynchronously. Use delay_for(interval) or delay_until(time) to deliver the email at some point in the future.
UserMailer.delay.welcome_email(@user.id)
UserMailer.delay_for(5.days).find_more_friends_email(@user.id)
UserMailer.delay_until(5.days.from_now).find_more_friends_email(@user.id)
So what is actually the difference between perfrom_async and delay? In which situations would I prefer the one over the other?
perform_async is a method for Workers
while delay is a method added by sidekiq to every other class to delay their own methods.
You'd use perform_async for a worker class that includes Sidekiq::Worker (it actually calls perform on the instance). Creating a class would allow you to have more control over what's going on, like how many times to retry, what to do when retries are exhausted and so on.
The delay class method uses a DelayedClass.perform to execute your method asynchronously. You can pass some options but you have far less granularity.
Personally I'd only use .delay for very, very simple things
O.K., say I have a BulkMailer, which sends many bulk_emails. Also, I have BulkEmailsWorker. What would I want to do:
class BulkEmailsWorker
def perform(email_id, recipients_ids)
bulk_email = BulkEmail.find(email_id)
recipients = User.find(recipients_ids)
recipients.each do |recipient|
BulkMailer.delay.bulk_email(bulk_email, recipient)
end
end
end
BulkEmailsWorker.perform(email_id, recipients_ids)
or
class BulkEmailsWorker
def perform(email_id, recipients_ids)
bulk_email = BulkEmail.find(email_id)
recipients = User.find(recipients_ids)
recipients.each do |recipient|
BulkMailer.bulk_email(bulk_email, recipient)
end
end
end
BulkEmailsWorker.perform_async(email_id, recipients_ids)
?
class BulkEmailsWorker
include Sidekiq::Worker
def perform(email_id, recipients_ids)
bulk_email = BulkEmail.find(email_id)
recipients = User.find(recipients_ids)
recipients.each do |recipient|
BulkMailer.bulk_email(bulk_email, recipient)
end
end
end
then
BulkEmailsWorker.perform_async(email_id, recipients_ids)
O.K., both of you recommend using perform_async for sending emails asynchronously. Why would the wiki then recommend Use delay to deliver your emails asynchronously.? Sorry for nagging, but I am really trying to understand the difference between the two. A few more examples:
In both of these examples people use the delay methods for asynchronous emails.
For example if you want to send a confirmation to 1 user , you use delay UserMailer.delay.confirmation_email(@user.id).
But in your case, you are sending a ton of emails so that more suitable for a worker.
In short both methods will work, you have to decide where you placing your code.
Your first example would, in a worker thread, wait for each email to be actually sent before the next can start to send. Your second example would, in a worker thread, enqueue all emails to be sent in parallel, in different threads, which would theoretically be faster.
I'm not advising one over the other, I do use .delay for Mailers because it's so convenient, you have to understand what it does and if it's what you want to do or not.
Also in any of the examples if one of those recipients were to be an invalid email, your worker would fail, attempt to retry and send the same emails over and over until hitting the point in the loop where the recipient is invalid. You have to be aware that your workers are going to run _at least once_.
O.K., thank you for your explanations. I would leave the issue open for now in case Mike Perham would like to add something.
You can close it, he can comment even if the issue is closed.
Well I think that people are less likely to open and read closed issues, but anyway, let's give it a try.
Delay is compatible with delayed_job syntax. Useful when porting from DJ to Sidekiq. Perform_async is preferred and Sidekiq's native API.
On May 20, 2014, at 0:00, AlexVPopov [email protected] wrote:
In the wiki I see the following examples:
From Getting started:
Send a message to be processed asynchronously:
HardWorker.perform_async('bob', 5)
You can also send messages by calling the delay method on a class method:User.delay.do_some_stuff(current_user.id, 20)
Also, from Delayed extensions:Use delay to deliver your emails asynchronously. Use delay_for(interval) or delay_until(time) to deliver the email at some point in the future.
UserMailer.delay.welcome_email(@user.id)
UserMailer.delay_for(5.days).find_more_friends_email(@user.id)
UserMailer.delay_until(5.days.from_now).find_more_friends_email(@user.id)So what is actually the difference between perfrom_async and delay? In which situations would I prefer the one over the other?
—
Reply to this email directly or view it on GitHub.
Thank you, this was exactly what I was looking for.
Most helpful comment
Delay is compatible with delayed_job syntax. Useful when porting from DJ to Sidekiq. Perform_async is preferred and Sidekiq's native API.