Tengo una cadena de apio que ejecuta algunas tareas. Cada una de las tareas puede fallar y volver a intentarlo. A continuación encontrará un ejemplo rápido:Volviendo a intentar las tareas fallidas del apio que forman parte de una cadena
from celery import task
@task(ignore_result=True)
def add(x, y, fail=True):
try:
if fail:
raise Exception('Ugly exception.')
print '%d + %d = %d' % (x, y, x+y)
except Exception as e:
raise add.retry(args=(x, y, False), exc=e, countdown=10)
@task(ignore_result=True)
def mul(x, y):
print '%d * %d = %d' % (x, y, x*y)
y la cadena:
from celery.canvas import chain
chain(add.si(1, 2), mul.si(3, 4)).apply_async()
Ejecución de las dos tareas (y suponiendo que nada falla), su conseguiría/Véase impresa:
1 + 2 = 3
3 * 4 = 12
Sin embargo, cuando la tarea de agregar falla la primera vez y tiene éxito en llamadas de reintentos posteriores, el resto de las tareas de la cadena no se ejecutan, es decir, la tarea de agregar falla, todas las demás tareas de la cadena no se ejecutan y después ew segundos, la tarea de agregar se ejecuta nuevamente y tiene éxito y el resto de las tareas de la cadena (en este caso mul.si (3, 4)) no se ejecuta.
¿El apio proporciona una manera de continuar las cadenas fallidas de la tarea que falló, en adelante? De lo contrario, ¿cuál sería el mejor enfoque para lograr esto y asegurarse de que las tareas de una cadena se ejecuten en el orden especificado y solo después de que la tarea anterior se haya ejecutado correctamente incluso si la tarea se reintenta varias veces?
Nota 1: El problema puede ser resuelto haciendo
add.delay(1, 2).get()
mul.delay(3, 4).get()
, pero estoy interesado en entender por qué las cadenas no funcionan con las tareas fallidas.
Decidí usar una tarea similar a una cadena que ejecuta todas las tareas que de otro modo estarían en una cadena, pero espera a que una tarea finalice antes de iniciar la otra, por ejemplo: 'task1.delay ([params]). obtener(); task2.delay ([params]). get(); task3.delay ([params]). get() '. La tarea similar a una cadena puede detectar las excepciones planteadas por cualquiera de las tareas y volver a intentarlo. – Andrei
Entonces, de su ejemplo, t1e y t2e tendrían que llamar a t2 y, respectivamente, t3, ¿verdad? – Andrei
El ejemplo es solo mi opinión sobre la posible sintaxis para la cadena. Significa que cada tarea siguiente ahora es de hecho un par de tareas, se llamará al primer elemento del par si no se produce una excepción/error en el paso anterior, y el segundo elemento es el controlador de excepción/error para el error del paso anterior. 't1e' significa' cadena de errores 't1' – anh