2011-11-22 7 views
7

Sono riuscito a ottenere task periodici che lavorano in django-sedano sottoclasse PeriodicTask. Ho provato a creare un'attività di test e l'ho fatta funzionare facendo qualcosa di inutile. Funziona.Arresto/Cancellazione di task periodici in Django-Sedano

Ora non riesco a fermarlo. Ho letto la documentazione e non riesco a scoprire come rimuovere l'attività dalla coda di esecuzione. Ho provato ad usare celeryctl e ad usare la shell, ma registry.tasks() è vuoto, quindi non vedo come rimuoverlo.

ho visto suggerimenti che avrei dovuto "revocare", ma per questo mi sembra necessario un ID attività, e non riesco a vedere come avrei trovato l'id del task.

Grazie.

risposta

21

Un compito è un messaggio, e un "task periodico" invia messaggi di attività a intervalli periodici. A ciascuna attività inviata verrà assegnato un ID univoco.

revoke sarà annullare un solo messaggio compito. Per ottenere l'id per un'attività, è necessario mantenere la traccia dell'ID inviato, ma è anche possibile specificare un ID personalizzato quando si invia un'attività.

non sono sicuro se si desidera annullare un singolo messaggio compito, o se si vuole interrompere l'attività periodica di inviare più messaggi, quindi ti elenco risposte per entrambi.

Non c'è modo integrato per mantenere l'id di un compito inviato con attività periodiche, ma si potrebbe impostare l'ID per ogni attività per il nome del task periodico, in questo modo l'id farà riferimento a qualsiasi attività inviata con l'attività periodica (di solito l'ultima). È possibile specificare un ID personalizzato in questo modo,

sia con il @periodic_task decoratrice:

@periodic_task(options={"task_id": "my_periodic_task"}) 
def my_periodic_task(): 
    pass 

o con l'impostazione CELERYBEAT_SCHEDULE:

CELERYBEAT_SCHEDULE = {name: {"task": task_name, 
           "options": {"task_id": name}}} 

Se si desidera rimuovere un task periodico è sufficiente rimuovere @periodic_task dalla codebase o rimuovere la voce da CELERYBEAT_SCHEDULE. Se si utilizza lo scheduler del database Django, è necessario rimuovere l'attività periodica dall'interfaccia di Django Admin.

PS1: revoke non si ferma un compito che è già stato avviato. Annulla solo le attività che non sono state ancora avviate. È possibile interrompere un'attività in esecuzione utilizzando revoke(task_id, terminate=True). Per impostazione predefinita, invierà il segnale TERM al processo , se si desidera inviare un altro segnale (ad esempio KILL) utilizzare revoke(task_id, terminate=True, signal="KILL").

PS2: revoke è un comando di controllo remoto, pertanto è supportato solo dai trasporti RabbitMQ e Redis broker. Se volete che il vostro compito di sostenere la cancellazione si dovrebbe fare in modo da memorizzare una bandiera cancelled in un database e fare controllare il compito che la bandiera quando inizia:

from celery.task import Task 

class RevokeableTask(Task): 
    """Task that can be revoked. 

    Example usage: 

     @task(base=RevokeableTask) 
     def mytask(): 
      pass 
    """ 

    def __call__(self, *args, **kwargs): 
     if revoke_flag_set_in_db_for(self.request.id): 
      return 
     super(RevokeableTask, self).__call__(*args, **kwargs) 
+0

Grazie per questa risposta estremamente approfondita. –

3

Solo nel caso questo può aiutare qualcuno ... Abbiamo avuto lo stesso problema al lavoro e disprezza alcuni sforzi per trovare qualche tipo di comando di gestione per rimuovere il compito periodico, non potremmo. Quindi ecco alcuni suggerimenti.

Probabilmente dovresti prima ricontrollare quale scheduler class stai utilizzando.

Il programma di pianificazione predefinito è celery.beat.PersistentScheduler, che sta semplicemente tenendo traccia degli ultimi tempi di esecuzione in un file di database locale (un shelve).

Nel nostro caso, stavamo usando la classe djcelery.schedulers.DatabaseScheduler.

django-sedano anche fornito con uno scheduler che memorizza il programma nel database Django

Anche se la documentazione non parlare di un modo per rimuovere i task periodici:

Utilizzando schedulatore django-celery è possibile aggiungere, modificare e rimuovere attività periodiche dall'amministratore di Django.

Si desidera eseguire la rimozione a livello di codice o tramite un comando (celery/management) in una shell.

Dal momento che non siamo riusciti a trovare una riga di comando, abbiamo usato la shell django/python:

$ python manage.py shell 
>>> from djcelery.models import PeriodicTask 
>>> pt = PeriodicTask.objects.get(name='the_task_name') 
>>> pt.delete() 

Spero che questo aiuta!