2011-10-06 9 views
22

En algunas condiciones, quiero hacer que una tarea de apio falle dentro de esa tarea. He intentado lo siguiente:Cómo hacer que una tarea de apio falle dentro de la tarea?

from celery.task import task 
from celery import states 

@task() 
def run_simulation(): 
    if some_condition: 
     run_simulation.update_state(state=states.FAILURE) 
     return False 

Sin embargo, la tarea continúa informando de haber tenido éxito:

sim.tasks.run_simulation Tarea [9235e3a7-c6d2-4219-BBC7-acf65c816e65] lograron 1.17847704887s : Falso

parece que el estado sólo puede ser modificada mientras que la tarea está en ejecución y una vez que se haya completado - apio cambia el estado a lo que estime es el resultado (consulte this question). ¿Hay alguna manera, sin fallar la tarea al hacer una excepción, de hacer que el apio regrese que la tarea ha fallado?

+0

¿Ha tratado de lanzar una excepción desde el interior de su código? – hymloth

+0

@hymloth Levantar una excepción hace que la tarea falle, lo que incluye enviarme un correo electrónico cada vez que eso sucede, algo que me gustaría evitar. Perdón por no estar claro, he cambiado la pregunta ahora. – Meilo

Respuesta

2

Recibí un interesting reply sobre esta pregunta de Ask Solem, donde propone un controlador 'after_return' para resolver el problema. Esta podría ser una opción interesante para el futuro.

Mientras tanto he resuelto el problema mediante la simple devolución de un 'fracaso' cadena de la tarea cuando quiero hacer que falle y luego la comprobación de que la siguiente manera:

result = AsyncResult(task_id) 
if result.state == 'FAILURE' or (result.state == 'SUCCESS' and result.get() == 'FAILURE'): 
    # Failure processing task 
+0

si la condición se podría escribir como 'result.state en READY_STATES | EXCEPTION_STATES: 'where' from aplery.states import READY_STATES, EXCEPTION_STATES, UNREADY_STATES' –

14

Una mejor manera de hacer esto es para actualizar el estado de la tarea como FAILURE y luego lanzar una excepción Ignore, debido a devolver cualquier valor registrará la tarea tan exitoso, un ejemplo:

from celery import Celery, states 
from celery.exceptions import Ignore 

app = Celery('tasks', broker='amqp://[email protected]//') 

@app.task(bind=True) 
def run_simulation(self): 
    if some_condition: 
     # manually update the task state 
     self.update_state(
      state = states.FAILURE, 
      meta = 'REASON FOR FAILURE' 
     ) 

     # ignore the task so no other state is recorded 
     raise Ignore() 
+0

Tenga en cuenta que esto _no_ activará la señal task_failure, por lo que los controladores que desee adjuntar a ellos no se activarán, lo cual no es bueno. –

Cuestiones relacionadas