取消Celery已经执行的任务?


91

我一直在阅读文档并进行搜索,但似乎找不到直接的答案:

您可以取消已经执行的任务吗?(由于任务已开始,需要一段时间,因此需要取消一半)

我在Celery FAQ的文档中找到了这个

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

但是我不清楚这是否会取消排队的任务,或者是否会杀死工作程序上正在运行的进程。感谢您能摆脱的光芒!

Answers:


179

撤销将取消任务执行。如果任务被吊销,工人将忽略该任务并且不执行它。如果您不使用持久撤销,则可以在worker重新启动后执行您的任务。

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

revoke具有终止选项,默认情况下为False。如果您需要终止正在执行的任务,则需要将Terminate设置为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
这正是我要的解释,谢谢!
dcoffey3296

1
这在分布式环境中有效吗?我的意思是,如果我在执行任务的多台计算机上有工作人员。芹菜是否跟踪任务在哪台机器上执行?
ksrini 2013年

1
是的 与工人的沟通是通过经纪人进行的。

4
result.revoke(终止= TRUE)应该做同样的事情,撤销(TASK_ID,终止= TRUE)
CamHart

9
而且,根据最近的Celery文档,使用终止选项是“管理员的最后选择”。您冒着终止另一个最近在该工作程序上开始的任务的风险。
kouk 2015年

38

在Celery 3.1中,更改了吊销任务API

根据Celery FAQ,您应该使用result.revoke:

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

或者,如果您只有任务ID:

>>> from proj.celery import app
>>> app.control.revoke(task_id)

25

@ 0x00mh的答案是正确的,但是最近的celery 文档说使用该terminate选项是“ 管理员的最后手段 ”,因为您可能不小心终止了同时开始执行的另一个任务。可能结合terminate=True使用更好的解决方案signal='SIGUSR1'(这将导致在任务中引发SoftTimeLimitExceeded异常)。


2
这个解决方案对我来说非常有效。SoftTimeLimitExceeded在任务中引发when时,将调用我的自定义清除逻辑(通过try/ except/ 实现finally)。我认为,这要比AbortableTask提供的服务更好(docs.celeryproject.org/en/latest/reference/…)。对于后者,您需要一个数据库结果后端,并且您必须手动并反复检查正在进行的任务的状态,以查看其是否已中止。
戴维·施耐德

2
据我所知,如果流程中还有其他任务要执行,无论如何它都会停止,这会更好吗,只会抛出不同的异常。
marxin

如果我worker_prefetch_multiplier = 1因为有几个长期运行的任务而使用了,则终止应该没问题-由于终止不会影响其他任务-我得到了正确的答案吗?@spicyramen
maffe


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.