我有很多的Appointment
是开始在一天的不同时间,无论是在车型:00:15:30:45。 我想触发代码活动开始前发送提醒1小时 。 什么是使用一个后台工作,以触发这一目标的最佳方式是什么? 我使用的钟表宝石以及这样我就可以安排Sidekiq工人。
Answer 1:
该clockwork
的宝石是固定的时间表作业(cron的更换)。 你要使用ActionMailer.delay_until
附带sidekiq
:
class Appointment
after_create :queue_reminder
def queue_reminder
MyMailer.delay_until(event_time - 1.hour).appointment_reminder(id)
end
end
见sidekiq
文档在这里: https://github.com/mperham/sidekiq/wiki/Delayed-Extensions
作为shock_one提到的,如果你更新一个新的日期约会,你就必须重新排队的提醒,并取消旧的。 您也想如果取消作业Appointment
被破坏。
为此,我建议你使用sidekiq-status
,和reminder_job_id
列。 你的Appointment
那么模型看起来是这样的:
class Appointment
before_save :queue_reminder, if: :event_time_changed?
after_destroy :cancel_reminder, if: :reminder_job_id?
def queue_reminder
cancel_reminder if reminder_job_id
self.reminder_job_id = MyMailer.delay_until(event_time - 1.hour)
.appointment_reminder(id)
end
def cancel_reminder
Sidekiq::Status.cancel reminder_job_id
end
end
Answer 2:
首先,你必须决定谁负责调度。 您可以有一个后台进程,它运行每15分钟,或者你可以使模型在其生命的某个时刻调度事件 - 可能创建后。
前者的解决方案更易于理解和维护,但后台进程将有很多无用的空循环。
在另一方面,后者的解决办法是更精确的。 根据需要将执行完全一样多的时间。 但是,它可能有困难,如果模型的变化:例如,在创建后的时间已被修改。 你需要以某种方式取消以前的事件,并安排一个新的。
文章来源: Best way to trigger an hour before event starts