2017-07-27 113 views
2

我可能不正確地使用芹菜。但是我正在開發的聊天機器人需要具有redis的芹菜異步任務。這是我正在使用的框架:http://microsoftbotframework.readthedocs.io/en/latest/asynctasks/如何從先前的芹菜任務中產生芹菜任務?

我的特殊使用案例目前需要我運行一個芹菜任務永遠並等待一段任意的時間,範圍從30分鐘到3天。像這樣的東西

@celery.task 
def myAsyncMethod(): 
    while true: 
     timeToWait = getTimeToNextAlarm() 
     sleep(timeToWait) 
     sendOutMessages() 

基本上,我有一個從不退出的異步過程。我很確定不應該像這樣使用芹菜。 所以我的問題是,我如何創建一個芹菜任務來處理第一個任務,產生一個任務並將其提交給芹菜隊列並退出。基本上是這樣的:

@celery.task 
def myImprovedTask(): 
    timeToWait = getTimeToNextAlarm() 
    sleep(timeToWait) 
    sendOutMessages() 
    myImprovedTask().delay() # recursive call to async method for next event 

不一定遞歸甚至像這樣的事,但它是芹菜的方式原本打算使用(短暫的任務,我相信?)

鉈; dr:我如何從另一個任務中創建一個芹菜任務並使原始任務退出?

請告訴我是否應該進一步解釋。謝謝。

+0

如果您想要定期運行任務,那麼它在這裏:http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html –

回答

1

如果你想從你的初始任務運行其他任務,只是把它作爲你通常會用Task.delay(),或​​做:

@celery.task 
def myImprovedTask(): 
    timeToWait = getTimeToNextAlarm() 
    sleep(timeToWait) 
    sendOutMessages() 
    myImprovedTask.delay() 

如果您再次調用同樣的任務沒關係。它會與delay()排隊,您的原始任務將返回,然後隊列中的下一個任務會運行。


這一切都是假設你實際上是在呼喚你的芹菜任務異步下。有時候不是這種情況,一個常見的罪魁禍首就是task-always-eager配置選項。默認情況下,它是禁用的,但(從docs):

如果task_always_eagerTrue所有任務將在本地通過阻斷,直到任務返回執行。 apply_async()Task.delay()將返回一個EagerResult實例,模擬API和AsyncResult的行爲,但結果已被評估。

也就是說,任務將在本地執行而不是發送到隊列。

所以,要確保你的芹菜配置包括:

task_always_eager = False 
+0

我沒有嘗試過。其實我應該提到。我使用了delay()本身。但過了一段時間,工作人員就沒有了,任務也沒有執行。 –

+0

你確定你的任務是異步的嗎?排隊後,應該返回'delay()',並完成前一個任務。 – randomir

+0

讓我快速嘗試一下,並且會盡快回復您。 –

0

如果任務沒有在當前進程註冊就可以使用 send_task()的名稱,而不是調用任務

在這裏的文檔http://docs.celeryproject.org/en/latest/reference/celery.html#celery.Celery.send_task

定義

這樣做,這樣,你必須明確地命名,如任務:

@celery.task(name="myImprovedTask") 
def myImprovedTask(): 

,這樣你就能夠與調用它:

app.send_task('myImprovedTask') 

如果你不喜歡這種方式(或者你在同一文件中的文件),你也可以用apply_asyncdelay喜歡叫它:

myImprovedTask.delay() 
myImprovedTask.apply_async() 
+0

嘿,謝謝你的建議。但是在調用myImprovedTask.delay()時,它直接進入下一個任務,而不退出第一個任務。 –