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

9
我正在尝试在自定义作业类中获取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
你想在 perform 方法中获取 Delayed::Job AR 对象吗? - Anatoly
确切地说!我需要检查对象的 start_time 是否已更改。 - Oliver
2个回答

10
如果您在自定义作业中定义了一个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

啊,抱歉。不小心点了踩的按钮,现在除非回答被编辑过,否则我无法撤销 :-(这个回答对我们来说是最有用的,也是我们实际选择的。谢谢。 - Vicente Quintans

8

You should handle this when you create the job:

   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)即可。

这有点像一个hack - 根据需要编辑handler方法。如果您的作业表很大或者您对其他类型的作业也进行了操作,则可以修改延迟作业表以具有类/对象ID,从而使代码更加清晰和更有效率的表扫描。

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

如何在Rails中使用delayed_job取消已安排的作业?


是的,但我正在一个 after_save 钩子中排队作业。所以假设事件推迟到第二天...那么事件又向后推迟了一天...然后两个作业都会被触发...或者我错了吗? - Oliver
1
我有一个类似的情况 - 在我排队作业之前,我会搜索表格以查找任何现有的作业。我将发布一些可能有用的代码。 - klochner
包括“and failed_at is null”的原因特别吗?如果任务A失败并等待重试,我们检查是否应启动任务B,不会导致任务重复吗? - Andrey Sereda
1
只有在所有重试都失败后,failed_at 才会被设置 -- “默认的 Worker.max_attempts 是 25。在此之后,作业将被删除(默认),或者保留在数据库中并设置“failed_at”。” - klochner
我知道这篇文章已经很老了,但是我觉得有点奇怪的是在作业中无法获取run_at属性,而必须在排队作业时将其作为参数传递。这真的是最优化的方式吗? - Kkulikovskis
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接