我需要为我的下一个项目安排一个调度程序,因为我使用Django进行编码,所以我去了Celery。
我正在寻找的是一个任务告诉Django何时完成的方式,因此我可以更新数据库并使用SSE告诉用户。只需将所有逻辑放入任务即可完成所有这些操作。但是,当我计划有几个芹菜工人时,我该怎么办?
我在网上发现了大量信息来涵盖单一工作人员案例,但如果您有多名工作人员,我会在很多方面解决问题。
我想到的是使用从工作者到Web服务器的http回调来让它知道任务已经完成。看celery.task.http看起来很有希望,但没有做我需要的。
解决方案是使用signals并挂接手动http调用吗?或者我走错了路?这不是一个常见的问题吗?如何更优雅地解决这个问题?
答案 0 :(得分:1)
那么,当你告诉Django时你是什么意思?我理解你是对的,django请求启动Celery任务,在这个任务完成的时候还活着吗?在那种情况下,你可以检查一些存储(数据库,memcached等)。并发送您的SSE。 看,有一种方法可以做到这一点。 1.你django查看发送任务到Celery,之后它进入无限循环(或循环超时60秒?)并等待memcached中的结果。
Celery获取任务执行,并将结果粘贴到memcached。
Django视图获得新结果,退出循环并发送您的SSE。
下一个变体是
Django视图将任务发送给Celery,并返回
Celery执行任务后,执行它会向您的django应用程序发出简单的HTTP请求。
Django收到来自Celery的http请求,解析params并再次向您的用户发送SSE
答案 1 :(得分:0)
以下是一些似乎符合我要求的代码:
在django设置中:
CELERY_ANNOTATIONS = {
"*": {
"on_failure": celery_handlers.on_failure,
"on_success": celery_handlers.on_success
}
}
在celery_handlers.py文件中包含:
def on_failure(self, exc, task_id, *args, **kwargs):
# Use urllib or similar to poke eg; api-int.mysite.com/task_handler/TASK_ID
pass
def on_success(self, retval, task_id, *args, **kwargs):
# Use urllib or similar to poke eg; api-int.mysite.com/task_handler/TASK_ID
pass
然后你可以设置api-int来使用类似的东西:
from celery.result import AsyncResult
task_obj = AsyncResult(task_id)
# Logic to handle task_obj.result and related goes here....