2014-03-28 61 views
2

我为一个异步任务使用Django和Celery。我需要知道如何正确地杀死Celery任务。Django /芹菜 - 如何杀死芹菜任务?

例如,我有一个Django鉴于这种芹菜任务:

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

要杀死这个“sometask”我可以用里面的任务一sys.exit()?例如:

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

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

最好的问候,

+1

task.revoke()可能会帮助 – navyad

回答

1

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

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

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

0

worker's guide

当一个人接到一个撤销请求时,它会跳过执行 任务,但除非终止选项设置也不会终止已经执行的任务。

如果终止设置工人孩子过程 处理任务将使用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