2010-09-03 7 views
35

Estoy programando un trabajo para ejecutar, digamos, 10 minutos. Cómo cancelar correctamente este trabajo en particular sin utilizar ningún tipo de campos extra sucios en el modelo, etc. ¿Hay alguna llamada para eliminar un trabajo en particular, o trabajos relacionados con un modelo específico, instancia, etc.?¿Cómo cancelar el trabajo programado con delayed_job en Rails?

Respuesta

49

exención de responsabilidad: No soy un usuario experto de delayed_job ...

"? ¿Hay alguna llamada para eliminar trabajo en particular, o puestos de trabajo relacionados con el modelo específico, ejemplo, etc"

Delayed :: Job es solo un objeto ActiveRecord para que pueda encontrar y destruir cualquiera de esos registros. Dependiendo de su caso de uso, esto podría manejarse de diferentes maneras. Si alguien va a destruirlos manualmente, esto podría manejarse a través de una interfaz de administrador en su aplicación web.

# list all jobs 
Delayed::Job.all 
# find a job by id 
job = Delayed::Job.find(params[:id]) 
# delete it 
job.delete 

si necesita alguna tarea de proceso de eliminación de trabajos por 'tipo de trabajo' se podía recorrer cada uno y eliminarlo si coincide con su trabajo; probar esto en escritura/consola

class MyJob < Struct.new(:some_value); 
    def perform 
     # ... 
    end 
end 

my_job = MyJob.new('xyz') 
job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now) 
job.name 
# => "MyJob" 
job.handler 
# => "--- !ruby/struct:MyJob \nsome_value: xyz\n" 

por lo visto lo anterior si desea eliminar todos los trabajos de tipo MyJob

Delayed::Job.all.each do |job| 
    if job.name == "MyJob" then 
     job.delete 
    end 
end 

esto puede o no puede ayudar a su situación? en muchos casos, es posible que desee eliminar un MyJob, pero solo cuando el atributo: some_value sea 'abc' y no 'xyz'. En este caso, es posible que deba implementar un 'nombre_pantalla' en su objeto MyJob. job.name se utilice este si es que existe

class MyJob < Struct.new(:user_id); 
    def perform 
     # ... 
    end 

    def display_name 
     return "MyJob-User-#{user_id}" 
    end 
end 

# store reference to a User 
my_job = MyJob.new(User.first.id) # users.id is 1 
job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now) 
job.name 
# => "MyJob-User-1" 
job.handler 
# => "--- !ruby/struct:MyJob \nuser_id: 1\n" 

esta manera usted podría ser más selectivos acerca de qué registros para eliminar?

esperemos que esto le brinde suficiente información sobre las posibles formas de manejarlo?

+1

Perfect Solution! – mdrozdziel

+10

Probablemente deberías usar "destruir" en lugar de "eliminar". –

+1

Dead handy, gracias por la respuesta realmente detallada. + –

7

delayed_job 3 introdujeron un atributo queue. Esto puede ser secuestrado para programar un trabajo cancelable.

class MyJob < Struct.new(:user_id) 
    def self.queue_name 
    "something-unique" 
    end 

    def perform 
    # ... 
    end 
end 

#scheduler 
my_job = MyJob.new(User.first.id) 
#'cancel' pending jobs first 
Delayed::Job.where(queue: my_job.class.queue_name).destroy_all 
#queue it up 
Delayed::Job.enqueue(my_job, 
    queue: my_job.class.queue_name, 
    run_at: 1.hour.from_now 
) 
+0

Realmente no recomendaría hacer las cosas de esta manera. El 'queue' está destinado a permitir que la aplicación se escale. Ya ha realizado una Struct personalizada, solo elija un nombre de atributo diferente que hizo house9. – Dex

Cuestiones relacionadas