Delayed :: Job的自动重试功能很棒,但是现在有一项我想手动重试的工作。有没有一种方法可以像我这样调用工作本身?
Delayed::Job.all[0].perform
或跑步或其他。我尝试了一些事情,并整理了文档,但是不知道如何执行作业的手动重试。
Answers:
手动呼叫工作
Delayed::Job.find(10).invoke_job # 10 is the job.id
如果作业成功运行,这不会删除该作业。您需要手动将其删除:
Delayed::Job.find(10).destroy
attempts
无法分配,update_attributes
因为它是受保护的属性。我只是这样做:dj = Delayed::Job.first; dj.run_at = Time.now; dj.attempts = 0; dj.save!;
Delayed::Job.where.not(last_error: nil).update_all(run_at: Time.current)
last_error
如果作业失败,这不会设置属性
Delayed::Worker.new.run(Delayed::Job.last)
完成后将删除该作业。
Delayed::Job.find_each(batch_size: 100) { |d| Delayed::Worker.new.run(d) }
通过找到工作并执行绩效,您可以按照您所说的完全做到这一点。
但是,我通常要做的只是将run_at设置回去,以便作业处理器再次将其拾取。
perform
延迟工作对象的方法。最接近的是Delayed::Job.find(10).payload_object.perform
,并且不应使用该值。
我在控制器中有一个方法用于测试目的,当我点击URL时,该方法只会重置所有延迟的作业。不是超级优雅,但对我来说很棒:
# For testing purposes
def reset_all_jobs
Delayed::Job.all.each do |dj|
dj.run_at = Time.now - 1.day
dj.locked_at = nil
dj.locked_by = nil
dj.attempts = 0
dj.last_error = nil
dj.save
end
head :ok
end
在开发环境中,rails console
按照Joe Martinez的建议,通过重试所有延迟的工作的好方法是:
Delayed::Job.all.each{|d| d.run_at = Time.now; d.save!}
run_at
在4.0.1中更新似乎还不够。我必须执行以下操作:Delayed::Job.where("failed_at is not null").each do |dj| dj.run_at = Time.now; dj.last_error = nil; dj.failed_at = nil; dj.save! end
把它放在一个初始化文件中!
module Delayed
module Backend
module ActiveRecord
class Job
def retry!
self.run_at = Time.now - 1.day
self.locked_at = nil
self.locked_by = nil
self.attempts = 0
self.last_error = nil
self.failed_at = nil
self.save!
end
end
end
end
end
那你就可以跑 Delayed::Job.find(1234).retry!
基本上,这会将作业重新放入队列并正常处理。
Delayed::Worker.new.run(Delayed::Job.first)
裁判