ruby-on-rails - rails - sidekiq perform now
Reintentar manualmente el trabajo en Delayed_job (9)
¡Pon esto en un archivo de inicializador!
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
Entonces puede ejecutar Delayed::Job.find(1234).retry!
Esto básicamente devolverá el trabajo a la cola y lo procesará normalmente.
Retrasada: la función de reintento automático de Job es excelente, pero hay un trabajo que deseo reintentar ahora manualmente. ¿Hay algún método al que pueda llamar en el trabajo como ...
Delayed::Job.all[0].perform
o correr, o algo. Probé algunas cosas y analicé la documentación, pero no pude encontrar la manera de ejecutar un intento manual de un trabajo.
En un entorno de desarrollo, a través de la rails console
, siguiendo la sugerencia de Joe Martinez, una buena forma de volver a intentar todos sus trabajos retrasados es:
Delayed::Job.all.each{|d| d.run_at = Time.now; d.save!}
Las respuestas anteriores pueden estar desactualizadas. Descubrí que necesitaba establecer fail_at, locked_by y locked_at en nil:
(para cada trabajo que quiera volver a intentar):
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!
Para llamar manualmente un trabajo
Delayed::Job.find(10).invoke_job # 10 is the job.id
Esto no elimina el trabajo si se ejecuta con éxito. Debe eliminarlo manualmente:
Delayed::Job.find(10).destroy
Puede hacerlo exactamente como lo dijo, encontrando el trabajo y ejecutándose.
Sin embargo, lo que generalmente hago es restablecer el run_at para que el procesador de tareas lo recupere nuevamente.
Si ha fallado el trabajo retrasado que necesita volver a ejecutar, solo tendrá que seleccionarlos y establecer que todo se refiera a un reintento fallido para anular:
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
Tengo un método en un controlador para fines de prueba que solo restablece todos los trabajos retrasados cuando presiono una URL. No es muy elegante, pero funciona muy bien para mí:
# 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
Delayed::Job.all.each(&:invoke_job)
Delayed::Worker.new.run(Delayed::Job.last)
Esto eliminará el trabajo una vez hecho.