使用django-celery chord,celery.chord_unlock会一直执行,不会调用提供的回调

时间:2012-05-03 20:05:00

标签: redis django-celery chord

我正在使用Django Celery和Redis来执行这样的一些任务:

header = [
    tasks.invalidate_user.subtask(args = (user)),
    tasks.invalidate_details.subtask(args = (user))
]

callback = tasks.rebuild.subtask()

chord(header)(callback)   

基本上与documentation中所述相同。

我的问题是,当调用此任务和弦时, celery.chord_unlock任务会一直重试header中的任务已成功完成,但由于chord_unlock永远不会完成, callback永远不会被称为

猜测我的问题是无法检测到来自header的任务已完成,我转向文档以了解如何对其进行自定义。我找到了a section,描述了如何实现同步,提供了一个示例,我缺少的是如何调用该示例函数(即是否有信号?)。

此外还有一个注意事项,此方法不适用于Redis后端:

  

除了Redis和Memcached之外的所有结果后端都使用它,它在标题中的每个任务之后递增计数器,然后在计数器超过集合中的任务数时应用回调。

但也说,Redis方法更好:

  

Redis和Memcached方法是一个更好的解决方案

那是什么方法?它是如何实现的?

那么,为什么chord_unlock从未完成,如何让它检测完成的header任务?

我正在使用:Django 1.4,芹菜2.5.3,django-celery 2.5.5,redis 2.4.12

3 个答案:

答案 0 :(得分:8)

您没有任务示例,但我遇到了同样的问题,我的解决方案也可能适用。

我对正在添加到和弦中的任务有ignore_result=True,其定义如下:

@task(ignore_result=True)

显然忽略了结果使得chord_unlock任务不知道它们是完整的。删除ignore_result后(即使任务只返回true),和弦也正确调用了回调。

答案 1 :(得分:0)

我遇到了同样的错误,我将代理更改为rabbitmq,chord_unlock正在工作,直到我的任务完成(2-3分钟任务)

使用redis时,任务结束,chord_unlock每1s只重试8-10次,所以回调没有正确执行。

[2012-08-24 16:31:05,804: INFO/MainProcess] Task celery.chord_unlock[5a46e8ac-de40-484f-8dc1-7cf01693df7a] retry: Retry in 1s [2012-08-24 16:31:06,817: INFO/MainProcess] Got task from broker: celery.chord_unlock[5a46e8ac-de40-484f-8dc1-7cf01693df7a] eta:[2012-08-24 16:31:07.815719-05:00]

... just like 8-10 times....

改变经纪人为我工作,现在我正在测试@Chris解决方案,我的回调函数永远不会收到来自标题子任务的结果:S,所以,它对我不起作用。


芹菜== 3.0.6

的django == 1.4

Django的芹菜== 3.0.6

redis的== 2.6

经纪人:Mac OS X上的redis-2.4.16

答案 2 :(得分:0)

这可能会导致一个问题;来自文档;

  

注意:

     

如果您使用带有Redis结果后端的和弦并且还覆盖了Task.after_return()方法,则需要确保调用super方法,否则将不会应用和弦回调。

def after_return(self, *args, **kwargs):
    do_something()
    super(MyTask, self).after_return(*args, **kwargs)

根据我的理解,如果您在任务中覆盖了after_return功能,则必须将其删除或至少调用超级

主题的底部:http://celery.readthedocs.org/en/latest/userguide/canvas.html#important-notes