创建重复的activejob失败

时间:2015-01-13 16:29:33

标签: ruby-on-rails ruby rails-activejob

我正在尝试在常规速率运行的rails 4.2中创建一个ActiveJob。这项工作是第一次被召唤,但它不会重新开始。在尝试调用perform_later之后,我的代码抛出了异常。

日志输出

[ActiveJob] Enqueued ProcessInboxJob (Job ID: 76a63689-e330-47a1-af92-8e4838b508ae) to Inline(default)
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Performing ProcessInboxJob from Inline(default)
ProcessInboxJob running...
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] [AWS S3 200 0.358441 0 retries] list_objects(:bucket_name=>"...",:max_keys=>1000)  

[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Enqueued ProcessInboxJob (Job ID: dfd3dd7a-06ab-4dba-9bbf-ce1ad606f7e5) to Inline(default) with arguments: {:wait=>30 seconds}
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Performed ProcessInboxJob from Inline(default) in 599.72ms
Exiting
/Users/antarrbyrd/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activejob-4.2.0/lib/active_job/arguments.rb:60:in `serialize_argument': Unsupported argument type: ActiveSupport::Duration (ActiveJob::SerializationError)

process_inbox_job.rb

class ProcessInboxJob < ActiveJob::Base
  queue_as :default
  #FREQUENCY = 3.minutes
  def perform()
    # do some work
  end
  # reschedule job
  after_perform do |job|
    self.class.perform_later(wait: 30.seconds)
  end
end

3 个答案:

答案 0 :(得分:2)

语法是self.class.set(wait:30.seconds).perform_later。但这并不是一种可靠的方式,就好像链断裂发生异常一样。您还必须安排初始作业。 如果您使用resque,则可以使用https://rubygems.org/gems/activejob-scheduler

答案 1 :(得分:2)

正如@bcd所说,你必须使用self.class.set(wait: 30.seconds).perform_later和支持排队的队列适配器,即不是默认(内联)适配器。

我发布了一个关于重新安排问题的不同观点,这可能有助于未来的读者。

如果引发异常,

after_perform将不会被调用,但会使其成为重新安排作业的不良位置。如果您在工作中遇到异常,请更好地挽救它(使用类方法rescue_from)并在您的后端尚未执行此操作时向您发送通知。

然后,您可以尝试解决问题(在数据或代码中)并重试(如果可以)或再次将类似作业排入队列。

对于调度部分,activejob-scheduler非常棒,不仅适用于resque,但有一些缺点。

它使用rufus-scheduler,它执行内存延迟,所以每当你的服务器重新启动时,你都会丢失所有的调度信息,这对于某些任务来说可能真的是一个问题(我在未来1个月安排任务并更新我的应用程序每周,这意味着每次重启。

您还失去了使用实际排队后端的所有优势,例如使用backburner的beanstalk。

ActiveJob-scheduler还声称在恰当的时间执行作业,这是错误的。 ActiveJob适配器在指定的时间运行,但根据您的设置,在实际执行作业之前可能需要一些时间,例如,当您在另一台服务器上运行作业时。

最后,对于初始计划,您可以包含一个代码,用于检查作业启动时是否存在作业,并在需要时进行计划。

总结一下,

是的,ActiveJob-Scheduler很棒,但是你会失去一些ActiveJob功能而且它不会做任何事情。

答案 2 :(得分:0)

根据您使用的排队系统,您可以尝试https://github.com/codez/delayed_cron_jobhttps://github.com/ondrejbartas/sidekiq-cron。使用DJ cron,您可以使用像rails_admin这样的UI来实际编辑cron正则表达式。 Sidekiq-cron为您提供Sinatra Web UI,您可以手动启动作业或暂停作业。