芹菜任务后的HTTP调用已经改变了状态

时间:2013-08-13 07:25:35

标签: django celery django-celery

我需要为我的下一个项目安排一个调度程序,因为我使用Django进行编码,所以我去了Celery

我正在寻找的是一个任务告诉Django何时完成的方式,因此我可以更新数据库并使用SSE告诉用户。只需将所有逻辑放入任务即可完成所有这些操作。但是,当我计划有几个芹菜工人时,我该怎么办?

我在网上发现了大量信息来涵盖单一工作人员案例,但如果您有多名工作人员,我会在很多方面解决问题。

我想到的是使用从工作者到Web服务器的http回调来让它知道任务已经完成。看celery.task.http看起来很有希望,但没有做我需要的。

解决方案是使用signals并挂接手动http调用吗?或者我走错了路?这不是一个常见的问题吗?如何更优雅地解决这个问题?

2 个答案:

答案 0 :(得分:1)

那么,当你告诉Django时你是什么意思?我理解你是对的,django请求启动Celery任务,在这个任务完成的时候还活着吗?在那种情况下,你可以检查一些存储(数据库,memcached等)。并发送您的SSE。 看,有一种方法可以做到这一点。 1.你django查看发送任务到Celery,之后它进入无限循环(或循环超时60秒?)并等待memcached中的结果。

  1. Celery获取任务执行,并将结果粘贴到memcached。

  2. Django视图获得新结果,退出循环并发送您的SSE。

  3. 下一个变体是

    1. Django视图将任务发送给Celery,并返回

    2. Celery执行任务后,执行它会向您的django应用程序发出简单的HTTP请求。

    3. 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....