Annullare un'attività già in esecuzione con Celery?


91

Ho letto il documento e ho cercato ma non riesco a trovare una risposta diretta:

Puoi annullare un'attività già in esecuzione? (poiché l'attività è iniziata, richiede un po 'di tempo e deve essere annullata a metà)

L'ho trovato dal documento in Celery FAQ

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

Ma non sono chiaro se questo annullerà le attività in coda o se ucciderà un processo in esecuzione su un lavoratore. Grazie per tutta la luce che puoi diffondere!

Risposte:


179

revoca annulla l'esecuzione dell'attività. Se un'attività viene revocata, i lavoratori ignorano l'attività e non la eseguono. Se non utilizzi revoche persistenti, l'attività può essere eseguita dopo il riavvio del lavoratore.

http://docs.celeryproject.org/en/latest/userguide/workers.html#worker-persistent-revokes

revoke ha un'opzione di terminazione che è False per impostazione predefinita. Se è necessario terminare l'attività in esecuzione, è necessario impostare terminate su True .

>>> from celery.task.control import revoke
>>> revoke(task_id, terminate=True)

http://docs.celeryproject.org/en/latest/userguide/workers.html#revoke-revoking-tasks


3
Questa è esattamente la spiegazione che stavo cercando, grazie!
dcoffey3296

1
Funziona in un ambiente distribuito? Voglio dire, se ho lavoratori su più macchine che stanno eseguendo attività. Il sedano tiene traccia di quale macchina è in esecuzione l'attività?
ksrini

1
Lo fa. La comunicazione con i lavoratori avviene tramite il broker.
mher

4
result.revoke (terminate = True) dovrebbe fare la stessa cosa di revoke (task_id, terminate = True)
CamHart

9
Inoltre, l'utilizzo dell'opzione di terminazione è "l'ultima risorsa per gli amministratori", come da documenti recenti di Celery. Corri il rischio di terminare un'altra attività che è stata avviata di recente su quel lavoratore.
kouk


25

La risposta di @ 0x00mh è corretta, tuttavia i recenti documenti sul sedano affermano che l'utilizzo terminatedell'opzione è "l' ultima risorsa per gli amministratori " perché potresti interrompere accidentalmente un'altra attività che è stata avviata nel frattempo. Probabilmente una soluzione migliore è combinare terminate=Truecon signal='SIGUSR1'(che causa la generazione dell'eccezione SoftTimeLimitExceeded nell'attività).


2
Questa soluzione ha funzionato molto bene per me. Quando SoftTimeLimitExceededviene sollevato nella mia attività, viene richiamata la mia logica di pulizia personalizzata (implementata tramite try/ except/ finally). Questo è molto meglio, a mio avviso, di quello che AbortableTaskoffre ( docs.celeryproject.org/en/latest/reference/… ). Con quest'ultimo, hai bisogno di un back - end dei risultati del database e devi controllare manualmente e ripetutamente lo stato di un'attività in corso per vedere se è stata interrotta.
David Schneider

2
Come è migliore, per quanto ho capito se c'è qualche altra attività raccolta dal processo, verrà comunque interrotta, verrà lanciata solo un'eccezione diversa.
marxin

Se lo uso worker_prefetch_multiplier = 1poiché ho solo poche attività a lunga esecuzione, la terminazione dovrebbe andare bene - poiché nessun altro compito verrà eseguito terminando - ho capito bene? @spicyramen
maffe,

1

Vedi le seguenti opzioni per le attività: time_limit , soft_time_limit (oppure puoi impostarlo per i lavoratori). Se si desidera controllare non solo il tempo di esecuzione, vedere l' argomento expires del metodo apply_async.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.