Solución:
Una tarea es un mensaje y una “tarea periódica” envía mensajes de tarea a intervalos periódicos. Cada una de las tareas enviadas tendrá asignada una identificación única.
revoke
solo cancelará un único mensaje de tarea. Para obtener la identificación de una tarea, debe realizar un seguimiento de la identificación enviada, pero también puede especificar una identificación personalizada cuando envía una tarea.
No estoy seguro de si desea cancelar un solo mensaje de tarea o si desea evitar que la tarea periódica envíe más mensajes, así que enumeraré las respuestas para ambos.
No hay una forma incorporada de mantener la identificación de una tarea enviada con tareas periódicas, pero puede establecer la identificación de cada tarea en el nombre de la tarea periódica, de esa manera la identificación se referirá a cualquier tarea enviada con la tarea periódica (generalmente el último). Puede especificar una identificación personalizada de esta manera,
ya sea con el @periodic_task
decorador:
@periodic_task(options={"task_id": "my_periodic_task"})
def my_periodic_task():
pass
o con el CELERYBEAT_SCHEDULE
configuración:
CELERYBEAT_SCHEDULE = {name: {"task": task_name,
"options": {"task_id": name}}}
Si desea eliminar una tarea periódica, simplemente elimine el @periodic_task
de la base de código, o elimine la entrada de CELERYBEAT_SCHEDULE
. Si está utilizando el programador de la base de datos de Django, debe eliminar la tarea periódica de la interfaz de administración de Django.
PS1: revoke
no detiene una tarea que ya se ha iniciado. Solo cancela las tareas que aún no se han iniciado. Puede finalizar una tarea en ejecución utilizando
revoke(task_id, terminate=True)
. De forma predeterminada, esto enviará el TERM
señal al proceso, si desea enviar otra señal (por ejemplo, KILL) utilice
revoke(task_id, terminate=True, signal="KILL")
.
PS2: revoke es un comando de control remoto, por lo que solo es compatible con los transportes de agentes de RabbitMQ y Redis. Si desea que su tarea sea compatible con la cancelación, debe hacerlo almacenando un cancelled
marca en una base de datos y haga que la tarea verifique esa marca cuando se inicie:
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)
En caso de que esto pueda ayudar a alguien … Tuvimos el mismo problema en el trabajo, y a pesar de algunos esfuerzos por encontrar algún tipo de comando de gestión para eliminar la tarea periódica, no pudimos. Así que aquí hay algunos consejos.
Probablemente primero debería verificar dos veces qué clase de programador está utilizando.
El planificador predeterminado es
celery.beat.PersistentScheduler
, que simplemente realiza un seguimiento de los últimos tiempos de ejecución en un archivo de base de datos local (una estantería).
En nuestro caso, estábamos usando el djcelery.schedulers.DatabaseScheduler
clase.
django-celery
también se envía con un programador que almacena el programa en la base de datos de Django
Aunque la documentación menciona una forma de eliminar las tareas periódicas:
Utilizando
django-celery
En el programador puedes agregar, modificar y eliminar tareas periódicas desde el administrador de Django.
Queríamos realizar la eliminación mediante programación o mediante un comando (apio / administración) en un shell.
Como no pudimos encontrar una línea de comando, usamos el shell django / python:
$ python manage.py shell
>>> from djcelery.models import PeriodicTask
>>> pt = PeriodicTask.objects.get(name="the_task_name")
>>> pt.delete()
¡Espero que esto ayude!