我觉得Clockwork,Sidekiq和Redis如何在Heroku上完全融合,因为Heroku每天至少重启一次dynos。
假设我有一个每天运行一次的工作人员,所以它在config/clock.rb
中配置为:
module Clockwork
every(1.day, 'Resend confirmation') { ResendConfirmationWorker.perform_async }
end
在此工作人员中,我获得了创建帐户但尚未在两天内确认帐户的所有用户,并向每个帐户重新发送确认电子邮件。
class ResendConfirmationWorker
include Sidekiq::Worker
sidekiq_options queue: :resend_confirmation, retry: false
def perform
d = Time.zone.now - 2.days
users = User.where.not(confirmation_sent_at: nil)
.where(confirmed_at: nil)
.where(created_at: d.beginning_of_day..d.end_of_day)
users.find_each do |user|
user.send_confirmation_instructions
end
end
end
让我们说星期一有人报名,这个工作在周三运行,找到他们,并向他们发送第二封确认电子邮件。然后dyno因任何原因重新启动,并且作业再次运行。他们还会收到另一封电子邮件。或者,如果重新启动发生在作业需要运行之前,那么他们就不会得到任何东西。
鉴于其在Heroku dyno中的“寿命”,发条如何有超过24小时的任何工作概念?有没有办法简单地管理这个限制,而不必经常将这种东西保存到数据库?
答案 0 :(得分:1)
如果你知道你将在每个星期三执行它,我建议使用Heroku Scheduler(https://devcenter.heroku.com/articles/scheduler)。它允许您以设定的时间间隔运行特定命令。减少复杂性。
答案 1 :(得分:0)
IMO如果要避免此类问题,您需要在数据库中获得更多信息。状态机可能有帮助,也可能是明确的second_confirmation_send_at
列。
这将允许您在工作中编写查询,如下所示:
users = User.where('confirmation_sent_at < ?', 2.days.ago)
.where(second_confirmation_send_at: nil)
如果查询一天多次运行,或者一天后意外运行,那么查询就不再关心了。