Die automatische Wiederholungsfunktion von Delayed :: Job ist großartig, aber es gibt einen Job, den ich jetzt manuell wiederholen möchte. Gibt es eine Methode, die ich bei der Arbeit selbst aufrufen kann ...
Delayed::Job.all[0].perform
oder laufen oder etwas. Ich habe ein paar Dinge ausprobiert und die Dokumentation gekämmt, konnte aber nicht herausfinden, wie eine manuelle Wiederholung eines Jobs ausgeführt werden sollte.
So rufen Sie einen Job manuell an
Delayed::Job.find(10).invoke_job # 10 is the job.id
Dies entfernt den Job nicht, wenn er erfolgreich ausgeführt wird. Sie müssen es manuell entfernen:
Delayed::Job.find(10).destroy
Delayed::Worker.new.run(Delayed::Job.last)
Dies entfernt den Job, nachdem er fertig ist.
Sie können es genau so machen, wie Sie es gesagt haben, indem Sie den Job finden und ausführen.
Im Allgemeinen setze ich jedoch run_at zurück, damit der Job-Prozessor es wieder aufnimmt.
Ich habe eine Methode in einem Controller zu Testzwecken, bei der alle verzögerten Jobs zurückgesetzt werden, wenn ich auf eine URL stoße. Nicht sehr elegant, aber es funktioniert super für mich:
# 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
Vorherige Antworten könnten veraltet sein. Ich fand, dass ich failed_at, locked_by und locked_at auf nil setzen musste:
(für jeden Job, den Sie wiederholen möchten):
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!
In einer Entwicklungsumgebung kann Rails console
, entsprechend dem Vorschlag von Joe Martinez, alle verspäteten Jobs wiederholt werden:
Delayed::Job.all.each{|d| d.run_at = Time.now; d.save!}
wenn Sie einen verzögerten Job nicht bestanden haben, den Sie erneut ausführen müssen, müssen Sie ihn nur auswählen und festlegen, dass alle Verweise auf fehlgeschlagene Wiederholung auf null gesetzt sind:
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
Delayed::Job.all.each(&:invoke_job)
Schreibe dies in eine Initialisierungsdatei!
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
Dann können Sie Delayed::Job.find(1234).retry!
ausführen.
Dadurch wird der Job im Allgemeinen in die Warteschlange zurückgesetzt und normal verarbeitet.