Difference between Action Job/Mailer's `deliver_now` and `deliver_later`

本小妞迷上赌 提交于 2019-12-06 17:06:10

问题


The common pattern for interfacing with ActionJob in Rails is to set up a Job with a perform() method that gets called asynchronously via perform_now or perform_later

In the special case of Mailers, you can directly call deliver_now or deliver_later since ActionJob is well integrated with ActionMailer.

The rails documentation has the following comments -

# If you want to send the email now use #deliver_now
UserMailer.welcome(@user).deliver_now

# If you want to send the email through Active Job use #deliver_later
UserMailer.welcome(@user).deliver_later

The wording makes it seem like deliver_now will not use ActiveJob to send the mail. Is that correct, and if so what's the true difference between deliver_now and deliver_later? Is one not asynchronous?

Similarly, does the same difference apply to perform_now and perform_later ?

Thanks!


回答1:


As you say in your question, deliver_now does not use ActiveJob.

Basically, deliver_later is asynchronous. When you use this method, the email is not send at the moment, but rather is pushed in a job's queue. If the job is not running, the email will not be sent. deliver_now will send the email at the moment, no matter what is the job's state. Here you can see the documentation for deliver methods.

According to your second question, perform_now will process the job immediately without sending to the queue. perform_later, however, will add the job to the queue, and as soon the job's queue is free, will perform the job. Here you can see the documentation for perform methods.




回答2:


In addition to what Daniel Batalla wrote, here's one more observation that I made: deliver_later seems to perform lazy evaluation, while deliver_now does not.

I have an ActiveRecord model with an additional attribute reset_token that is not stored in the database (this is from Michael Hartl's railstutorial.org; the model stores a hashed version of the token in the reset_digest column).

When executing deliver_now, accessing the @model's reset_token attribute inside the mailer view yields the reset token as expected. However, when executing deliver_later, @model.reset_token is always nil. It appears as if deliver_later updates the model with database data, and because reset_token is an additional attribute that is not backed by the database, it will be nil at that point. (The code documentation is too deeply nested for me to be able to verify this in the source.)

Michael uses deliver_now in the tutorial. I don't know he does this to avoid lazy evaluation. But it took me a while to realize that I just had to change deliver_later to deliver_now to make my tests pass.



来源:https://stackoverflow.com/questions/32619366/difference-between-action-job-mailers-deliver-now-and-deliver-later

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!