我可能用错了芹菜。但是我正在开发的聊天机器人需要带有 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;dr:如何从另一个任务中创建芹菜任务并使原始任务退出?
请告诉我是否应该进一步解释。谢谢。
如果你想从你的初始任务运行另一个任务,只需像通常对Task.delay()
或Task.apply_async()
一样调用它:
@celery.task
def myImprovedTask():
timeToWait = getTimeToNextAlarm()
sleep(timeToWait)
sendOutMessages()
myImprovedTask.delay()
再次调用同一任务并不重要。它与delay()
一起排队,您的原始任务返回,然后队列中的下一个任务运行。
所有这些都是在假设您实际上是异步调用 Celery 任务的情况下进行的。有时情况并非如此,一个常见的罪魁祸首是task-always-eager
配置选项。默认情况下,它是禁用的,但是(来自文档(:
如果
task_always_eager
True
,所有任务都将通过阻塞在本地执行,直到任务返回。apply_async()
和Task.delay()
将返回一个EagerResult
实例,该实例模拟 API 和AsyncResult
的行为,但结果已经评估。也就是说,任务将在本地执行,而不是发送到队列。
因此,请确保您的芹菜配置包括:
task_always_eager = False
如果任务未在当前进程中注册,您可以使用 send_task(( 改为按名称调用任务
如此处文档中所定义 http://docs.celeryproject.org/en/latest/reference/celery.html#celery.Celery.send_task
app.send_task('task_name')
这样做,您必须显式命名任务,例如:
@celery.task(name="myImprovedTask")
def myImprovedTask():
然后你可以用以下命令调用它:
app.send_task('myImprovedTask')
如果您不喜欢这种方式(或者您将文件放在同一个文件中(,您也可以使用 apply_async 或延迟调用它,如下所示:
myImprovedTask.delay()
myImprovedTask.apply_async()