2010-10-10 23 views
30

Il Celery documentation suggerisce che è una cattiva idea avere compiti in attesa dei risultati di altri compiti ... Ma la soluzione suggerita (vedi intestazione "buona") lascia un qualcosa a desiderare. Nello specifico, non esiste un modo chiaro per riportare il risultato del sottotask al chiamante (è anche un po 'brutto).Python + Celery: concatenare lavori?

Quindi, c'è un modo per "concatenare" i lavori, quindi il chiamante ottiene il risultato del lavoro finale? Ad esempio, per utilizzare il add esempio:

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

In alternativa, è OK per tornare istanze di Risultato? Per esempio:

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

Ciò avrebbe lasciato il risultato del lavoro di “finale” nella catena potrebbe essere retrived con un semplice:

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

Cosa proponete avrebbe funzionato bene. Non vedo alcuna alternativa, vero? – asksol

risposta

30

si può fare con una catena di sedano. Vedere 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 

lavoro concatenazione:

# 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

Ciao, sto cercando di ottenere il risultato di un processo incatenato come questo suggerimento, ma avverti: '[2016-09-15 16: 20: 52,684: WARNING/Worker-7] /Library/Python/2.7/site- packages/celery/result.py: 45: RuntimeWarning: non chiamare mai result.get() all'interno di un'attività! 'Vedere http: // docs.celeryq.org/it/latest/userguide/tasks.html # task-synchronous-subtasks'' ' In Celery 3.2 questo si tradurrà in un'eccezione pari a generata anziché essere semplicemente un warning Sto usando le sottocomponenti concatenate come 'result = chain (..., ..., ...). delay(). get()' puoi spiegare perché solleva un problema nonostante le subtask siano gestite da metodo di catena? – user305883