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

时间:2014-06-06 07:59:52

标签: ruby-on-rails cron background-process rake-task

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

2 个答案:

答案 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-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

答案 1 :(得分:0)

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

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

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