我有很多Appointment
型号,它们在一天的不同时间开始,可以在:00,:15,:30,:45 。我想在活动开始前触发代码以发送提示 1小时。使用后台工作程序触发此操作的最佳方法是什么?我正在使用clockwork宝石,所以我可以安排Sidekiq工人。
答案 0 :(得分:2)
clockwork
gem用于固定计划作业(替代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
答案 1 :(得分:0)
首先,您必须决定由谁负责安排。您可以拥有一个后台进程,每15分钟运行一次,或者您可以让模型在其生命的某个时刻安排事件 - 可能是在创建之后。
前一种解决方案更易于理解和维护,但后台进程将有许多无用的空循环。
另一方面,后一种解决方案更精确。它将根据需要执行完全相同的次数。但是,如果模型更改,则可能会遇到困难:例如,时间在创建后已经过修改。您需要以某种方式取消之前的活动,并安排一个新活动。