2010-07-22 16 views
53

Opóźnienie: funkcja automatycznego powtarzania zadania jest świetna, ale istnieje zadanie, które chcę ręcznie spróbować ponownie. Czy istnieje sposób, w jaki mogę zadzwonić do samego zadania, jak ...Ręczne ponawianie pracy w trybie Delayed_job

Delayed::Job.all[0].perform 

lub uruchomić, lub coś. Próbowałem kilku rzeczy i przeczesywałem dokumentację, ale nie mogłem wymyślić, jak wykonać ręczną próbę wykonania pracy.

+2

'Opóźniony :: Worker.new.run (Delayed :: Job.first)' [ref] (http://stackoverflow.com/a/20146200/495132) –

Odpowiedz

88

Aby ręcznie wywołać pracę

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

nie usunąć zadanie, jeśli jest prowadzony z powodzeniem. Musisz usunąć go ręcznie:

+10

Alternatywa zasugerowana przez @joe jest bezpieczniejsza, zwłaszcza jeśli praca musi wiedzieć, czy działa w skrypcie/konsoli lub w pracy biegacza. Spróbuj ustawić w kolejce zadanie do natychmiastowego ponowienia. Opóźnione :: Job.first.update_attributes (: tries => 0,: run_at => Time.teraz:: failed_at => nil,: locked_by => zero,: locked_at => zero) –

+8

"Próby" nie mogą być przypisane w "update_attributes', ponieważ jest to atrybut chroniony. Po prostu: dj = Delayed :: Job.first; dj.run_at = Time.now; dj.attempts = 0; dj.save!; ' – Anjan

+0

Aby zrobić to masowo, zadziałało to (około 100 zadań). Opóźnione :: Job.where.all.each {| dj | dj.run_at = Time.now; dj.attempts = 0; dj.save!} – tobinharris

11

Możesz zrobić to dokładnie tak, jak powiedziałeś, znajdując pracę i wykonując przedstawienie.

Zazwyczaj jednak ustawię parametr run_at, aby procesor roboczy odtworzył go ponownie.

+1

Nie ma metody "wykonaj" dla pracy opóźnionej obiekt. Najbliższy jest 'Opóźniony :: Job.find (10) .payload_object.perform', a nie należy go używać. – lulalala

8

Mam metodę w kontroler do celów testowych, który po prostu resetuje wszystkie opóźnione zadania, gdy uderzyłem w adres URL. Nie bardzo eleganckie, ale działa świetnie dla mnie:

# 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

użyj update_all .. to jedno połączenie z bazą danych. – baash05

+1

Nie można użyć update_all ebcause próby są chronione atrybutem –

+1

update_all używa SQL bezpośrednio i dlatego nie wywołuje walidacji (lub chronionych atrybutów itp.). – Michael

4

W środowisku rozwoju, poprzez rails console, po sugestii Joe Martineza, to dobry sposób, aby ponowić wszystkie opóźnione pracy jest:

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

Aktualizacja 'run_at' w wersji 4.0.1 nie wydaje się wystarczająca. Musiałem wykonać następujące czynności: 'Delayed :: Job.where (" failed_at is not null "). Każdy do | dj | dj.run_at = Time.now; dj.last_error = nil; dj.failed_at = zero; dj.save! end' – steakchaser

6

Prior odpowiedzi Powyższe może być nieaktualny. Uważam, że muszę ustawić failed_at, locked_by i locked_at do zera:

(dla każdego zadania, które ma ponowić próbę):

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! 
21
Delayed::Worker.new.run(Delayed::Job.last) 

To usunie zadanie po jego Gotowe.

+0

Usunie to, nawet jeśli się nie powiedzie – aledustet

+0

Dla wszystkich opóźnionych zadań możesz zrobić "Opóźnione :: Job.find_each (batch_size: 100) {| d | Opóźnione :: Worker.new.run (d)} ' – MatayoshiMariano

3

jeśli zawiodły opóźnione zadanie, które trzeba ponownie uruchomić, a następnie trzeba będzie je tylko wybrać i ustawić wszystko odnosi się do nieudanej ponownego null:

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

umieścić to w pliku inicjatora!

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 

Następnie można uruchomić Delayed::Job.find(1234).retry!

to będzie w zasadzie trzymać pracę z powrotem do kolejki i przetwarza je normalnie.

Powiązane problemy