2010-10-10 29 views
30

El Celery documentation sugiere que es una mala idea tener tareas pendientes de los resultados de otras tareas ... Pero la solución sugerida (consulte el encabezado "bueno") deja algo que desear. Específicamente, no hay una forma clara de devolver el resultado de la subtarea a la persona que llama (también es feo).Python + Celery: ¿Trabajos de encadenamiento?

Entonces, ¿hay alguna forma de "encadenar" los trabajos, por lo que la persona que llama obtiene el resultado del trabajo final? Por ejemplo, para utilizar el add ejemplo:

>>> add3 = add.subtask(args=(3,)) 
>>> add.delay(1, 2, callback=add3).get() 
6 

Alternativamente, ¿está bien para volver instancias de Resultado? Por ejemplo:

@task 
def add(x, y, callback=None): 
    result = x + y 
    if callback: 
     return subtask(callback).delay(result) 
    return result 

Esto permitiría que el resultado del trabajo de “final” de la cadena podría retrived con un simple:

result = add(1, 2, callback=add3).delay() 
while isinstance(result, Result): 
    result = result.get() 
print "result:", result 
+0

Lo que usted propone funcionaría bien. No veo ninguna alternativa, ¿verdad? – asksol

Respuesta

30

usted puede hacerlo con una cadena de apio. Ver https://celery.readthedocs.org/en/latest/userguide/canvas.html#chains

@task() 
def add(a, b): 
    time.sleep(5) # simulate long time processing 
    return a + b 

trabajo en cadena:

# import chain from celery import chain 
# the result of the first add job will be 
# the first argument of the second add job 
ret = chain(add.s(1, 2), add.s(3)).apply_async() 

# another way to express a chain using pipes 
ret2 = (add.s(1, 2) | add.s(3)).apply_async() 

... 

# check ret status to get result 
if ret.status == u'SUCCESS': 
    print "result:", ret.get() 
+0

Hola, estoy tratando de obtener el resultado de un proceso encadenado como esta sugerencia, pero reciba una advertencia: '[2016-09-15 16: 20: 52,684: ADVERTENCIA/Worker-7] /Library/Python/2.7/site- packages/apio/result.py: 45: RuntimeWarning: ¡Nunca llame a result.get() dentro de una tarea! 'Ver http: // docs.celeryq.org/es/latest/userguide/tasks.html # task-synchronous-subtasks'' ' En Apio 3.2 esto dará como resultado una excepción que será elevada en lugar de solo ser un advertencia. Estoy utilizando subtareas encadenadas como 'result = chain (..., ..., ...). delay(). get()' puede explicar por qué plantea un problema a pesar de que las subtareas son manejadas por método de cadena? – user305883