在活动开始前一小时触发的最佳方式

我有许多Appointment模型,它们在一天的不同时间开始,在:00,:15,:30,:45 。 我想在事件开始前1小时触发代码发送提醒。 使用后台工作程序触发此操作的最佳方法是什么? 我正在使用发条gem,所以我可以安排Sidekiq工人。

clockworkgem用于固定的计划工作(替代cron)。 您将要使用sidekiq附带的ActionMailer.delay_until

 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-statusreminder_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 

首先,您必须决定由谁负责安排。 您可以拥有一个后台进程,每15分钟运行一次,或者您可以让模型在其生命的某个时刻安排事件 – 可能是在创建之后。

前一种解决方案更易于理解和维护,但后台进程将有许多无用的空循环。

另一方面,后一种解决方案更精确。 它将根据需要执行完全相同的次数。 但是,如果模型更改,则可能会遇到困难:例如,时间在创建后已经过修改。 您需要以某种方式取消之前的活动,并安排一个新活动。