2010-09-03 6 views
35

Sto pianificando un lavoro da eseguire in 10 minuti. Come cancellare correttamente questo particolare lavoro senza utilizzare nessun tipo di campi extra sporchi nel modello e così via. C'è qualche chiamata per rimuovere un lavoro particolare, o lavori relativi a modello, istanza, ecc. Specifici?Come annullare un lavoro pianificato con delayed_job in Rails?

risposta

49

disclaimer: io non sono un utente esperto di delayed_job ...

"? C'è qualche chiamata per rimuovere particolare lavoro, o di posti di lavoro legati al modello specifico, esempio, etc"

ritardati :: Il lavoro è solo un oggetto ActiveRecord in modo da poter trovare e distruggere uno di quei record. A seconda del tuo caso d'uso, questo potrebbe essere gestito in modi diversi. Se qualcuno sta per distruggerli manualmente, questo potrebbe essere gestito attraverso un'interfaccia di amministrazione nella tua app web.

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

se avete bisogno di un po 'di compiti processo di eliminazione di posti di lavoro entro 'tipo di lavoro' si potrebbe ciclo attraverso ogni uno e cancellarlo se corrisponde il vostro lavoro; provare questo nello script/console

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" 

modo Ciò premesso, se si voleva eliminare tutti i processi di tipo MyJob

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

questo può o non può aiutare per la vostra situazione? in molti casi potresti voler eliminare un MyJob ma solo dove l'attributo: some_value era 'abc' e non 'xyz'. In questo caso potrebbe essere necessario implementare un 'display_name' sul tuo oggetto MyJob. job.name lo userà se esiste

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" 

in questo modo si potrebbe essere più selettivi su quali record eliminare?

si spera che questo ti dia abbastanza informazioni sui possibili modi per gestirlo?

+1

Soluzione perfetta! – mdrozdziel

+10

Probabilmente dovresti usare "destroy" invece di "delete". –

+1

Dead handy, grazie per la risposta davvero dettagliata. + –

7

delayed_job 3 ha introdotto un attributo queue. Questo può essere dirottato per pianificare un lavoro cancellabile.

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

Non consiglierei davvero di fare le cose in questo modo. Il'queue 'è pensato per consentire all'applicazione di scalare. Hai già seguito una Struct personalizzata, basta scegliere un nome di attributo diverso house9. – Dex