[Django]-Cancel an already executing task with Celery?

241πŸ‘

βœ…

revoke cancels the task execution. If a task is revoked, the workers ignore the task and do not execute it. If you don’t use persistent revokes your task can be executed after worker’s restart.

https://docs.celeryq.dev/en/stable/userguide/workers.html#worker-persistent-revokes

revoke has an terminate option which is False by default. If you need to kill the executing task you need to set terminate to True.

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

https://docs.celeryq.dev/en/stable/userguide/workers.html#revoke-revoking-tasks

πŸ‘€mher

60πŸ‘

In Celery 3.1, the API of revoking tasks is changed.

According to the Celery FAQ, you should use result.revoke:

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

or if you only have the task id:

>>> from proj.celery import app
>>> app.control.revoke(task_id)
πŸ‘€Rockallite

38πŸ‘

@0x00mh’s answer is correct, however recent celery docs say that using the terminate option is β€œa last resort for administrators” because you may accidentally terminate another task which started executing in the meantime. Possibly a better solution is combining terminate=True with signal='SIGUSR1' (which causes the SoftTimeLimitExceeded exception to be raised in the task).

πŸ‘€kouk

8πŸ‘

Per the 5.2.3 documentation, the following command can be run:

    celery.control.revoke(task_id, terminate=True, signal='SIGKILL')

where
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])

Link to the doc: https://docs.celeryq.dev/en/stable/reference/celery.app.control.html?highlight=revoke#celery.app.control.Control.revoke

πŸ‘€Amogh Joshi

6πŸ‘

You define celery app with broker and backend something like :

from celery import Celery
celeryapp = Celery('app', broker=redis_uri, backend=redis_uri)

When you run send task it return unique id for task:

task_id = celeryapp.send_task('run.send_email', queue = "demo")

To revoke task you need celery app and task id:

celeryapp.control.revoke(task_id, terminate=True)
πŸ‘€omkar more

4πŸ‘

In addition, unsatisfactory, there is another way(abort task) to stop the task, but there are many unreliability, more details, see:
http://docs.celeryproject.org/en/latest/reference/celery.contrib.abortable.html

πŸ‘€xiaopo

2πŸ‘

from celery.app import default_app

revoked = default_app.control.revoke(task_id, terminated=True, signal='SIGKILL')
print(revoked)

1πŸ‘

See the following options for tasks: time_limit, soft_time_limit (or you can set it for workers). If you want to control not only time of execution, then see expires argument of apply_async method.

πŸ‘€simplylizz

0πŸ‘

from celery.result import AsyncResult
task = AsyncResult(task_id)
task.revoke()
πŸ‘€Nabaz Maaruf

Leave a comment