如何在Active Job(Rails 4.2)中安排定期作业?

lui*_*gal 37 ruby-on-rails ruby-on-rails-4 rails-activejob

我在Rails中找到了这个 Schedule一次性工作, 但这只显示了如何一次性安排.我有兴趣安排一份经常性的工作.

Delayed_job有这个

self.delay(:run_at => 1.minute.from_now)
Run Code Online (Sandbox Code Playgroud)

我如何在Rails 4.2/Active Job中做类似的事情?

ome*_*cat 25

与rab3的答案类似,由于ActiveJob支持回调,我正在考虑做类似的事情

class MyJob < ActiveJob::Base
  after_perform do |job|
    # invoke another job at your time of choice 
    self.class.set(:wait => 10.minutes).perform_later(job.arguments.first)
  end

  def perform(the_argument)
    # do your thing
  end
end
Run Code Online (Sandbox Code Playgroud)

activejob回调

  • 做`before_perform` 更好吗?它将避免由 perform 方法引起的所有延迟 (4认同)

Jua*_*tas 23

如果要将作业执行延迟到10分钟后,有两个选项:

  1. SomeJob.set(wait: 10.minutes).perform_later(record)

  2. SomeJob.new(record).enqueue(wait: 10.minutes)

延迟到现在使用的特定时刻wait_until.

  1. SomeJob.set(wait_until: Date.tomorrow.noon).perform_later(record)

  2. SomeJob.new(record).enqueue(wait_until: Date.tomorrow.noon)

详情请参阅http://api.rubyonrails.org/classes/ActiveJob/Base.html.

对于重复性工作,你只需要SomeJob.perform_now(record)输入一个cronjob(无论何时).

如果你使用Heroku,只 SomeJob.perform_now(record)需要安排一个预定的rake任务.请在此处阅读有关预定rake任务的更多信息:Heroku调度程序.

  • 请注意,`wait_until`需要一个`ActiveSupport :: TimeWithZone`实例,而`wait`需要一个`Date`实例.相反,传递给`wait_until`的对象需要响应`:to_f`并返回等待的"纪元秒"(1970年1月1日以来的秒数) (2认同)

raf*_*fb3 11

您可以在执行结束时重新排队作业

class MyJob < ActiveJob::Base
  RUN_EVERY = 1.hour

  def perform
    # do your thing

    self.class.perform_later(wait: RUN_EVERY)
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 这实际上不是一个可靠的解决方案:如果发生异常,链断裂,一些后端适配器似乎不接受ActiveSupport :: Duration参数.您还必须首次手动启动作业. (12认同)
  • 我们曾经这样做,由于一些原因它不可靠.1)它没有考虑你的工作时间.如果你的工作需要5分钟,那就是每天2小时,这意味着你大约需要22个工作/ 24小时.(这可以通过时钟数学来解决)2)由于工人失灵,工作有可能无法运行.如果你的工作在运行时查看"x的最近一小时",它将永远不会赶上.3)在反弹的情况下不保证确保块运行.如果你在heroku上运行,并在作业运行时进行部署,那么你就有可能杀死这个进程. (2认同)