2016-05-18 32 views
15

Come gli stati di Celeria documentation, l'attività già in esecuzione non verrà interrotta chiamando .revoke(), a meno che non sia impostato terminate=True. Ma non è raccomandato, perché ucciderà il lavoratore stesso, che potrebbe aver già avviato un'altra attività. Ciò significa che non esiste un modo affidabile e stabile per farlo?Esiste un modo per arrestare in modo non violento una determinata attività di sedano?

EDIT: celery.contrib.abortable non mi va bene, perché, come afferma la documentazione, funziona solo con i back-end del database.

+0

Dipende l'operazione che si sta tentando di interrompere (di rete, file, operazioni di database, ecc), si prega di dare un'occhiata a questo esempio: http://stackoverflow.com/questions/37039941/celery- python-revoke Nel mio caso il mio compito principale richiama i processi figli che non sono terminati a meno che non invii un segnale SIGKILL. – spicyramen

+0

Possibile duplicato di [Arresto del compito di sedano con garbo] (http://stackoverflow.com/questions/16493364/stopping-celery-task-gracefully) – Louis

risposta

2

Un'attività in esecuzione è un sottoprocesso in esecuzione del worker (quando si utilizza prefork), ciò significa che l'unico modo per interrompere un'attività consiste nell'uccidere il sottoprocesso che lo sta eseguendo.

Si può provare a sperimentare la propria implementazione della gestione degli eventi revoke cercando di capire l'ID del sottoprocesso e uccidere solo quello, ma sinceramente non si sa se vale e se può davvero funzionare.

Penso che una risposta breve sia impossibile.

Comunque uccidendo il lavoratore è necessario a volte, soprattutto nelle fasi iniziali di progetti in cui è ancora necessario per dimensionare correttamente le risorse, basta assicurarsi che si accede da qualche parte le attività in esecuzione in modo da poterli riprogrammare o semplicemente usare CELERY_ACKS_LATE

+0

"In ogni caso uccidere il lavoratore non è insolito" Quale * solita condizione * dovrebbe garantire il fine di un lavoratore su un sistema di produzione? Ho usato Celery per alcuni anni e il * solo * tempo in cui un lavoratore viene forzatamente terminato è quando il sito deve essere spento per manutenzione. – Louis

+1

Dipende dal caso d'uso, ho lavorato per un grosso sito Web della comunità in quei giorni e abbiamo riscontrato alcuni problemi durante le ore di punta. I lavoratori stavano assorbendo molta memoria e il congelamento. Ovviamente ciò era dovuto al fatto che non ci aspettavamo che carico e lavoratore non fossero correttamente dimensionati. Ma posso dirti che in un anno è successo un paio di volte, senza considerare il crash totale della macchina dovuto ad altri fattori. –

+0

Ho chiarito la risposta dopo il commento di Louis. –

1

È possibile inviare un segnale HUP anziché TERMINALE che riavvia con garbo il processo figlio senza uccidere l'operatore.

In [80]: import signal 

In [81]: x = add.delay(1, 2) 

In [82]: x.revoke(terminate=True, signal=signal.SIGHUP) 
+0

"Oltre a fermarsi e riavviare il worker, è anche possibile riavviare il worker utilizzando il segnale HUP, ma si noti che il worker sarà responsabile del riavvio stesso, quindi questo è soggetto a problemi e non è raccomandato in produzione" [Source] (http://docs.celeryproject.org/en/latest/userguide/workers.html) – Louis

+0

@Louis Se si ha un lavoratore con una concorrenza di 4, ha 4 processi in esecuzione 4 attività alla volta. Ora riavviare è una cattiva idea solo revocare un'attività, poiché potrebbe interrompere altri processi. Il comando precedente riavvierà solo il singolo processo che stava eseguendo quell'attività. – ChillarAnand