Usando django-celery chord, celery.chord_unlock sigue ejecutándose para siempre sin llamar a la devolución de llamada proporcionada

Estoy usando Django Celery con Redis para ejecutar algunas tareas como esta:

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

callback = tasks.rebuild.subtask()

chord(header)(callback)   

Así que básicamente lo mismo que se indica en documentación.

Mi problema es que cuando se llama a este acorde de tarea, celery.chord_unlock la tarea sigue reintentando para siempre. Tareas en header terminar con éxito, pero debido a chord_unlock nunca se hace, callback nunca se llama.

Supongo que mi problema es no poder detectar que las tareas de header están terminados, recurrí a la documentación para ver cómo se puede personalizar. He encontrado una sección, que describe cómo se implementa la sincronización, se proporciona un ejemplo, lo que me falta es cómo hago para que se llame a esa función de ejemplo (es decir, ¿hay una señal para esto?).

Además, hay una nota de que este método no se usa con el backend de Redis:

Esto lo utilizan todos los backends de resultados, excepto Redis y Memcached, que incrementan un contador después de cada tarea en el encabezado y luego aplican la devolución de llamada cuando el contador excede la cantidad de tareas en el conjunto.

Pero también dice que el enfoque de Redis es mejor:

El enfoque de Redis y Memcached es una solución mucho mejor

¿Qué enfoque es ese? ¿Cómo se implementa?

Entonces, ¿por qué es chord_unlock nunca hecho y cómo puedo hacer que se detecte terminado header ¿Tareas?

Estoy usando: Django 1.4, apio 2.5.3, django-celery 2.5.5, redis 2.4.12

preguntado el 03 de mayo de 12 a las 21:05

3 Respuestas

No tiene un ejemplo de sus tareas, pero tuve el mismo problema y mi solución podría aplicarse.

Tuve ignore_result=True sobre las tareas que estaba agregando a un acorde, definidas así:

@task(ignore_result=True)

Aparentemente, ignorar el resultado hace que la tarea chord_unlock no sepa que están completos. Después de eliminar ignore_result (incluso si la tarea solo devuelve verdadero), el acorde llamó a la devolución de llamada correctamente.

Respondido 18 Jul 12, 22:07

Tuve el mismo error, cambié el intermediario a rabbitmq y chord_unlock funciona hasta que finaliza mi tarea (tareas de 2-3 minutos)

cuando se usa redis, la tarea finaliza y chord_unlock solo se vuelve a intentar como 8-10 veces cada 1 s, por lo que la devolución de llamada no se estaba ejecutando correctamente.

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

cambiar el corredor funcionó para mí, ahora estoy probando la solución @Chris y mi función de devolución de llamada nunca recibe los resultados de las subtareas del encabezado: S, por lo tanto, no funciona para mí.


apio==3.0.6

django==1.4

django-apio==3.0.6

redis==2.6

intermediario: redis-2.4.16 en Mac OS X

Respondido 24 ago 12, 22:08

Esto podría causar un problema tal que; De la documentación;

Nota:

Si está utilizando acordes con el backend de resultados de Redis y también anula el método Task.after_return(), debe asegurarse de llamar al supermétodo o, de lo contrario, no se aplicará la devolución de llamada de acordes.

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

Según tengo entendido, si ha sobrescrito after_return función en su tarea, debe eliminarse o al menos llamar súper uno.

Fondo del tema:http://celery.readthedocs.org/en/latest/userguide/canvas.html#important-notes

contestado el 26 de mayo de 14 a las 09:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.