Используя 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