创建重复的activejob失败

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

日志输出

[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 

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

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

我发帖就重新安排的问题提出了不同的观点,这可能有助于未来的读者。

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

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

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

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

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

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

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

总结一下,

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

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