我正在使用任务来完成后台工作。例如我在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
首先发送邮件是为了确保此任务正在运行。 第二封邮件是用户通知他丢失了他的徽章。
我还有其他任务,其中一封邮件工作正常。
但在其他任务中,不会发送邮件。只有当我删除deliver_later并使用传递时,才会发送邮件。
我不想使用传递,因为它会在发送邮件之前暂停。
您是否知道导致deliver_later无法正常使用rails任务?
答案 0 :(得分:1)
我正在处理发送电子邮件的Rails 5.0.1应用程序中的rake任务。我使用的是ActiveJob的异步适配器的默认设置(开发模式)。我还在开发中使用了letter_opener gem,以便在我的浏览器中弹出电子邮件而不是发送。
当我使用.deliver_now运行每个电子邮件的任务时,一切都很好。
为了让任务快速完成,我切换了rake任务,以便它生成的每封电子邮件都使用.deliver_later而不是.deliver_now排队。
我可以看到电子邮件被ActiveJob排队了:
[ActiveJob]排队的ActionMailer :: DeliveryJob ......
但是在开信刀中没有弹出电子邮件。
事实证明,问题在于我并不了解:异步如何工作。基本上,正在发生的事情是:async是一个内存队列,只有创建它的进程才会存在。使用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