2010-07-22 88 views
53

Delayed :: Job的自动重试功能非常好,但我现在需要手动重试。有没有一种方法,我可以打电话给工作本身就像...Delayed_job中手动重试作业

Delayed::Job.all[0].perform 

或运行,或其他。我尝试了几件事情,并梳理了文档,但无法弄清楚如何执行手动重试作业。

+2

'Delayed :: Worker.new.run(Delayed :: Job.first)'[ref](http://stackoverflow.com/a/20146200/495132) – 2015-01-06 11:12:43

回答

88

手动调用工作

Delayed::Job.find(10).invoke_job # 10 is the job.id 

如果成功运行该不会删除工作。您需要手动删除它:

Delayed::Job.find(10).destroy 
+10

@joe建议的替代方案更安全一些,特别是如果作业需要知道它是在脚本/控制台还是在作业运行器中运行。 试试这个将作业排队以便立即重试 Delayed :: Job.first.update_attributes(:attempts => 0,:run_at => Time。现在,:failed_at => nil,:locked_by => nil,:locked_at =>无) – 2012-03-10 00:16:03

+8

'attempts'不能在'update_attributes'中分配,因为它是一个受保护的属性。我只是这样做:'dj = Delayed :: Job.first; dj.run_at = Time.now; dj.attempts = 0; dj.save!;' – Anjan 2012-08-20 11:00:16

+0

要做到这一点en-masse这工作(约100个工作) Delayed :: Job.where.each {| dj | dj.run_at = Time.now; dj.attempts = 0; dj.save!} – tobinharris 2014-03-24 13:22:05

11

您可以通过查找作业和执行作业完全按照您的说法进行作业。

但是,我通常所做的只是将run_at设置回来,以便作业处理器再次选取它。

+1

延迟作业没有'perform'方法目的。最接近的是'Delayed :: Job.find(10).payload_object.perform',一个不应该使用它。 – lulalala 2012-06-14 10:05:03

8

我在控制器中有一个方法用于测试目的,当我点击一个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 
+1

使用update_all ..这是一个调用数据库。 – baash05 2012-10-22 05:55:07

+1

您不能使用update_all ebcause企图被保护属性 – 2013-03-13 13:31:04

+1

update_all直接使用SQL,因此不会调用验证(或受保护的属性等) – Michael 2016-05-04 13:06:31

4

在开发环境中,通过rails console,继乔·马丁内斯的建议,重新尝试所有的延迟就业的好方法是:

Delayed::Job.all.each{|d| d.run_at = Time.now; d.save!} 
+5

在4.0.1中更新'run_at'似乎不够。我必须做到以下几点:'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!结束' – steakchaser 2014-05-13 18:43:10

6

上述现有答案可能已过时。我发现我需要设置failed_at,locked_by和locked_at为nil:

(对于要重试每个作业):

d.last_error = nil 
d.run_at = Time.now 
d.failed_at = nil 
d.locked_at = nil 
d.locked_by = nil 
d.attempts = 0 
d.failed_at = nil # needed in Rails 5/delayed_job (4.1.2) 
d.save! 
1
Delayed::Job.all.each(&:invoke_job) 
21
Delayed::Worker.new.run(Delayed::Job.last) 

这将删除作业后,它是完成。

+0

即使它失败,它也会将其删除 – aledustet 2016-12-08 21:19:48

+0

对于所有延迟的作业,您可以执行'Delayed :: Job.find_each(batch_size:100){| d | Delayed :: Worker.new.run(d)}' – MatayoshiMariano 2017-03-10 13:41:14

3

,如果你失败了,你需要重新运行延误的工作,那么你只需要选择它们并设置就绪指未能重试空:

Delayed::Job.where("last_error is not null").each do |dj| 
    dj.run_at = Time.now.advance(seconds: 5) 
    dj.locked_at = nil 
    dj.locked_by = nil 
    dj.attempts = 0 
    dj.last_error = nil 
    dj.failed_at = nil 
    dj.save 
end 
0

在初始化文件将这个!

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!

这基本上都会坚持工作回到队列中,通常对其进行处理。