delivery_later在rails任务中工作不好



我正在使用任务来完成后台作业。例如,我在lib/tasks:中的remove_badges.rake文件

desc "Remove expired badges rake task"
task :remove_expired_badges => :environment do
message = "remove_expired_badges is running now."
HostMailer.send_system_info_mail(message).deliver_later
BadgeHost.all.each do |b|
if b.expire_at < Time.now
begin
b.destroy
puts "An expired badge successfully deleted."
host = b.host
badge = b.badge
HostMailer.send_badge_removed_email(host, badge).deliver_later
rescue
puts "Failed to destroy expired badge."
end
end
end
end

第一封邮件是给我自己的,因为我确信这个任务正在运行。第二封邮件是给用户的,通知他丢失了徽章。

我还有其他任务,其中一个任务是邮件运行良好。

但在其他任务中,不会发送邮件。只有当我删除delivery_later并使用delivery时,才会发送邮件。

我不想使用快递,因为它正在暂停,直到邮件发送。

你知道是什么原因导致delivery_later不能很好地处理rails任务吗?

我刚刚在Rails 5.0.1应用程序中处理一个发送电子邮件的rake任务。我使用的是ActiveJob的默认设置:异步适配器(开发模式)。我还在开发中使用letter_opener gem,这样电子邮件就会在我的浏览器中弹出,而不是发送。

当我使用.dever_now.运行每封电子邮件的任务时,一切看起来都很好

为了让任务快速完成,我切换了rake任务,使它生成的每封电子邮件都以.devert_later而不是.dever_now.排队

我可以看到ActiveJob:排队的电子邮件

[ActiveJob]已排队ActionMailer::DeliveryJob。。。

但在信件开启器中并没有弹出任何电子邮件。

事实证明,问题是我不明白异步是如何工作的。基本上,发生的事情是:异步是一个内存中的队列,它只会持续到创建它的进程存在的时间。使用rake任务时,电子邮件会正确排队(在内存中),但随后任务结束,内存队列会被清空。但这种情况发生在给ActiveJob线程任何处理时间之前。

为了测试事情是否在开发中起作用,以下任何一项都会起作用:

Use .deliver_now
Add a sleep(5) to the end of your rake task (just for manual testing ... delete that before you commit)
Switch to a different ActiveJob adapter that stores the jobs in some durable queue / db and runs as a separate process from your rake task

答案取自:http://stevechanin.blogspot.com/2017/05/deliverlater-not-working-in-rake-tasks.html

最新更新