Django /芹菜 - 如何杀死芹菜任务?

时间:2014-03-28 15:48:37

标签: django celery

我正在使用Django和Celery进行一项异步任务。我需要知道如何正确杀死Celery任务。

例如,我在Django视图中有这个Celery任务:

...
sometask.delay(some1, some2)
...

要杀死这个“sometask”我可以在任务中使用sys.exit()吗?例如:

@shared_task
def sometask(some1, some2):
    ...
    ...
    if some1 == False:
        sys.exit('Abort!')

这个sys.exit()可以在Celery任务中运行吗?

最诚挚的问候,

2 个答案:

答案 0 :(得分:3)

你提到'杀死芹菜任务',你也提到'sys.exit()'。 通常,杀死进程涉及一些外部干扰以终止进程。使用sys.exit()意味着进程从内部终止。

考虑到这一点,这里有几个选择 - 1.如果你想要芹菜任务结束:只需从函数(sometask)返回,任务就会结束​​。如果您没有例外地返回,则该任务将被视为成功。如果您引发了异常,则该任务将被视为失败。无论哪种方式,任务都将结束,除非你有重试的逻辑。请注意,执行任务的池工作进程可能仍然处于活动状态,具体取决于工作节点的maxtasksperchild参数。 2.如果您想从过程外部结束芹菜任务: a)如果你知道taskid,你可以尝试撤销任务。 b)如果你想要“杀死”(TERM)正在执行任务的工作进程,那么这是另一回事。您需要处理相关信号。我认为TERM信号只发送给主工作进程而不是池工作进程。这就是我记得的,因为我试图解决一个类似的问题。

从您尝试在代码中使用sys.exit()的方式来看,我认为1就是您所需要的。

答案 1 :(得分:0)

来自worker's guide

  

当工作人员收到撤销请求时,它将跳过执行   任务,但除非设置了terminate选项,否则它不会终止已经执行的任务。

     

如果设置了终止工作子进程   处理任务将被终止

使用app.control.revoke(task_id,terninate=True),这将终止工作人员的子流程,所有其他任务都没问题。

我在这里开始两项任务并终止其中一项:

app.control.revoke("c028bd99-8394-4e2c-86ab-440ca2290d67",terninate=True)
[2015-11-19 04:55:09,458: INFO/MainProcess] Received task: celery.starmap[73c53773-2dd5-40d0-b9a0-83b2f12eba9b]
[2015-11-19 04:55:09,465: INFO/MainProcess] Received task: celery.starmap[c028bd99-8394-4e2c-86ab-440ca2290d67]
[2015-11-19 04:57:13,993: INFO/MainProcess] Tasks flagged as revoked: c028bd99-8394-4e2c-86ab-440ca2290d67
[2015-11-19 04:59:32,684: INFO/MainProcess] Terminating c028bd99-8394-4e2c-86ab-440ca2290d67 (15)
[2015-11-19 04:59:32,781: ERROR/MainProcess] Task celery.starmap[c028bd99-8394-4e2c-86ab-440ca2290d67] raised unexpected: Terminated(15,)
Traceback (most recent call last):
      File "....../lib/python2.7/site-packages/billiard/pool.py", line 1678, in _set_terminated
        raise Terminated(-(signum or 0))
    Terminated: 15