我正在使用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
答案 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....
芹菜== 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