2010-07-22 24 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!

這基本上都會堅持工作回到隊列中,通常對其進行處理。

相關問題