2014-03-28 104 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