如何从以前的芹菜任务中产生芹菜任务?

时间:2017-07-27 14:21:49

标签: python asynchronous redis celery botframework

我可能错误地使用了芹菜。但我正在开发的聊天机器人需要使用带有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

不一定是递归的,甚至不喜欢这样,但是芹菜最初的用途是什么(对于我认为的短期任务?)

Tl;博士:如何从另一个任务中创建芹菜任务并使原始任务退出?

告诉我是否应该进一步解释。感谢。

2 个答案:

答案 0 :(得分:1)

如果您想从初始任务中运行其他任务,只需像通常使用Task.delay()Task.apply_async()一样调用它:

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

如果再次调用相同的任务,则无关紧要。它被delay()排队,你的原始任务返回,然后队列中的下一个任务就会运行。

所有这些都假设您实际上是异步调用Celery任务。有时这不是一个案例,常见的罪魁祸首是task-always-eager配置选项。默认情况下,它已被禁用,(来自docs):

  

如果 task_always_eager True所有任务都将通过阻止在本地执行,直到任务返回apply_async()Task.delay()会返回EagerResult个实例,该实例会模拟AsyncResult的API和行为,但结果已经过评估。

     

也就是说,任务将在本地执行,而不是发送到队列。

因此,请确保您的Celery配置包括:

task_always_eager = False

答案 1 :(得分:0)

  

如果任务未在当前流程中注册,则可以使用   send_task()通过名称来调用任务

在此处的文档[{3}}

中定义
app.send_task('task_name')

这样做,您必须明确命名任务,如:

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

然后你可以用:

来调用它
app.send_task('myImprovedTask')

如果您不喜欢这种方式(或者您将文件放在同一个文件中),您也可以使用http://docs.celeryproject.org/en/latest/reference/celery.html#celery.Celery.send_taskapply_async来调用它:

myImprovedTask.delay()
myImprovedTask.apply_async()