2017-07-27 127 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()时,它直接进入下一个任务,而不退出第一个任务。 –