es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cadena de tareas en Celery: si alguna tarea falla, hacer x, en caso contrario y.

Estoy empezando a trabajar con Cadena de Tareas en mi proyecto de Django. Tengo la siguiente función:

def orquestar_tareas_para_cuenta(id_cuenta):

# Obtener la cuenta, establecer el estado en 'SYNC' hasta que la cadena esté completa
cuenta = Account.objects.get(id=id_cuenta)
cuenta.status = "SYNC"
cuenta.save()

cadena = task1.s(id_cuenta) | task2.s() | task3.s()
cadena()

# Si alguna de las tareas en la cadena falla, establecer cuenta.status en 'ERROR'
# de lo contrario, establecer cuenta.status en 'OK'

La cadena funciona como se esperaba, pero no estoy seguro de cómo recibir retroalimentación de la cadena y actualizar la cuenta en función de los resultados.

En otras palabras, me gustaría establecer el estado de la cuenta en ‘ERROR’ si alguna de las tareas en la cadena falla, de lo contrario, me gustaría establecer el estado de la cuenta en ‘OK’.

Estoy confundido con la documentación de Celery sobre cómo manejar un error con un if/else, como he comentado en las dos últimas líneas anteriores.

¿Alguien tiene experiencia con esto?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para manejar errores en una cadena de Celery y actualizar el estado de la cuenta en función de los resultados, puedes utilizar el callback on_error proporcionado por Celery. El callback on_error se llama cuando alguna tarea de la cadena falla.

    Puedes definir la función de callback que actualizará el estado de la cuenta a ‘ERROR’ y pasarla al método .on_error() de la cadena. Aquí tienes un ejemplo:

    def update_account_status(task_id, exc, traceback=None):
        account = Account.objects.get(id=account_id)
        account.status = 'ERROR'
        account.save()
    
    chain = task1.s(account_id) | task2.s() | task3.s()
    chain.on_error(update_account_status)
    result = chain()
    if result.failed():
        account = Account.objects.get(id=account_id)
        account.status = 'ERROR'
        account.save()
    else:
        account = Account.objects.get(id=account_id)
        account.status = 'OK'
        account.save()
    

    En este ejemplo, definimos la función update_account_status que recibe tres argumentos: task_id, exc y traceback. El task_id es el id de la tarea que ha fallado, exc es la excepción que ha causado el fallo y traceback es el objeto traceback de la excepción. Solo necesitamos el account_id para actualizar el estado de la cuenta, así que no utilizamos los otros dos argumentos.

    La función update_account_status recupera el objeto de cuenta, establece el estado a ‘ERROR’ y lo guarda en la base de datos.

    Luego creamos la cadena y llamamos al método .on_error(), pasando la función update_account_status como argumento.

    Después de eso, llamamos a la cadena y almacenamos el resultado en la variable result. Si alguna tarea en la cadena falló, result.failed() devolverá True.

    Finalmente, recuperamos el objeto de cuenta y actualizamos el estado en función del resultado: si alguna tarea falló, establecemos el estado a ‘ERROR’, de lo contrario lo establecemos como ‘OK’.

    ¡Espero que esto te ayude!

Comments are closed.