Используя django-celery chord, celery.chord_unlock продолжает выполняться вечно, не вызывая предоставленный обратный вызов

Я использую Django Celery с Redis для выполнения нескольких таких задач:

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

callback = tasks.rebuild.subtask()

chord(header)(callback)   

Так что в основном так же, как указано в документации.

Моя проблема в том, что когда этот аккорд задачи называется, celery.chord_unlockзадание повторяется вечно. Задачи в header закончить успешно, но из-за chord_unlock никогда не будет сделано, callbackникогда не называется.

Предполагаю, что моя проблема в том, что я не могу обнаружить, что задачи из header Закончив, я обратился к документации, чтобы посмотреть, как это можно настроить. Я нашел раздел, описывающий, как реализована синхронизация, приведен пример, но мне не хватает, как мне заставить эту функцию вызываться (т.е. есть ли сигнал для этого?).

Далее есть примечание, что этот метод не используется с бэкэндом Redis:

Это используется всеми бэкэндами результата, кроме Redis и Memcached, которые увеличивают счетчик после каждой задачи в заголовке, затем применяют обратный вызов, когда счетчик превышает количество задач в наборе.

Но и говорит, что Redis лучше подходит:

Подход Redis и Memcached - намного лучшее решение

Какой это подход? Как это реализовано?

Итак, почему chord_unlock никогда не сделано, и как я могу сделать это обнаружить законченным header задачи?

Я использую: Django 1.4, сельдерей 2.5.3, django-сельдерей 2.5.5, redis 2.4.12

3 ответа

У вас нет примера ваших задач, но у меня была та же проблема, и моё решение могло бы подойти.

я имел ignore_result=True на задачах, которые я добавлял в аккорд, определялся так:

@task(ignore_result=True)

Видимо, игнорирование результата делает так, что задача chord_unlock не знает, что они выполнены. После того, как я удалил ignore_result (даже если задача возвращает только true), аккорд правильно вызвал обратный вызов.

У меня была та же ошибка, я изменил брокер на rabbitmq и chord_unlock работает до тех пор, пока моя задача не завершится (задачи 2-3 минуты)

при использовании redis задача завершается, и chord_unlock повторяется только 8-10 раз каждые 1 с, поэтому обратный вызов не выполняется правильно.

[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

Джанго ==1.4

Джанго-сельдерей ==3.0.6

Redis==2.6

брокер: redis-2.4.16 на Mac OS X

Это может вызвать такую ​​проблему; Из документации;

Замечания:

Если вы используете аккорды с бэкендом результата Redis, а также переопределяете метод Task.after_return(), вам нужно обязательно вызвать супер метод, иначе обратный вызов chord не будет применен.

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

Другие вопросы по тегам