Delayed_Job:访问作业元数据和/或避免重复作业

时间:2011-07-27 14:50:09

标签: ruby-on-rails ruby-on-rails-3 delayed-job

我正在尝试在自定义作业类中获取run_at日期时间。我的代码看起来像这样:

class MyCustomJob < Struct.new(:my_object)

  def perform
    if self.run_at == my_object.start_time
      # process the job
    end
  end

end

我也尝试了Delayed::Job.find(self),但没有运气。

提前致谢

2 个答案:

答案 0 :(得分:11)

如果在自定义作业上定义before方法,则工作人员会在调用perform之前将延迟的作业实例传递给您:

class MyCustomTask

  def before(job)
    @job = job
  end

  def perform
    # has access to @job object. 
    # You may need to call @job.reload to see in-flight changes to object in the database.
  end
end

答案 1 :(得分:8)

您应该在创建作业时处理此问题:

   priority = 0
   run_time = my_object.start_time
   Delayed::Job.enqueue(MyCustomJob.new(my_object), priority, run_time)

https://github.com/tobi/delayed_job/wiki

如果您的作业未在预期时间运行,您可能会将它们安排为UTC:

http://www.gregbenedict.com/2009/08/19/is-delayed-job-run_at-datetime-giving-you-fits/

要检查现有作业的队列,您可以执行以下操作:


class MyCustomJob < Struct.new(:object_id)

  def self.exists?(object_id)
    Delayed::Job.where(['handler = ? and failed_at is null',handler(object_id)]).count(:all) > 0
  end

  def self.handler(object_id)
    "--- !ruby/struct:MyCustomJob \nobject_id: #{object_id}\n"
  end

  def perform
    my_object = MyObject.find(object_id)
    my_object.do_stuff
  end
end

然后在排队前检查MyCustomJob.exists?(my_object.id)

这有点像黑客 - 根据需要编辑handler方法。我会修改delayed_jobs表,使其具有类/ object_id,以便在作业表很大或者对其他类型的作业执行此操作时,使代码更清晰,表扫描更有效。

这个问题看起来也很相关:

How to cancel scheduled job with delayed_job in Rails?