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

Oli*_*ver 9 ruby-on-rails delayed-job ruby-on-rails-3

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

class MyCustomJob < Struct.new(:my_object)

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

end
Run Code Online (Sandbox Code Playgroud)

我也试过Delayed::Job.find(self)但没有运气.

提前致谢

小智 11

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

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
Run Code Online (Sandbox Code Playgroud)


klo*_*ner 8

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

   priority = 0
   run_time = my_object.start_time
   Delayed::Job.enqueue(MyCustomJob.new(my_object), priority, run_time)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

这有点像黑客 - handler根据需要编辑方法.我会修改delayed_jobs表,使其具有类/ object_id,以便在作业表较大或与其他类型的作业一起使用时,使代码更清晰,更有效的表扫描.

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

如何在Rails中使用delayed_job取消预定作业?