Come posso estrarre il risultato di un'attività se non conosco in precedenza quale attività è stata eseguita? Ecco il programma di installazione: Dato il seguente sorgente ('tasks.py'):Recupera il risultato da 'task_id' in Celery da un'attività sconosciuta
from celery import Celery
app = Celery('tasks', backend="db+mysql://u:[email protected]/db", broker = 'amqp://guest:[email protected]:5672//')
@app.task
def add(x,y):
return x + y
@app.task
def mul(x,y):
return x * y
con RabbitMQ 3.3.2 in esecuzione a livello locale:
marcs-mbp:sbin marcstreeter$ ./rabbitmq-server
RabbitMQ 3.3.2. Copyright (C) 2007-2014 GoPivotal, Inc.
## ## Licensed under the MPL. See http://www.rabbitmq.com/
## ##
########## Logs: /usr/local/var/log/rabbitmq/[email protected]
###### ## /usr/local/var/log/rabbitmq/[email protected]
##########
Starting broker... completed with 10 plugins.
con sedano 3.1.12 in esecuzione a livello locale:
-------------- [email protected] v3.1.12 (Cipater)
---- **** -----
--- * *** * -- Darwin-13.2.0-x86_64-i386-64bit
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app: tasks:0x105dea3d0
- ** ---------- .> transport: amqp://guest:**@localhost:5672//
- ** ---------- .> results: disabled
- *** --- * --- .> concurrency: 8 (prefork)
-- ******* ----
--- ***** ----- [queues]
-------------- .> celery exchange=celery(direct) key=celery
posso quindi importare il metodo e recuperare il risultato con il 'task_id':
from tasks import add, mul
from celery.result import AsyncResult
result = add.delay(2,2)
task_id = result.task_id
result.get() # 4
result = AsyncResult(id=task_id)
result.get() # 4
result = add.AsyncResult(id=task_id)
result.get() # 4
# and the same for the 'mul' task. Just imagine I put it here
Nell'esempio seguente ho suddiviso questi passaggi tra i processi. In un processo che ho recuperare il 'task_id' in questo modo:
from tasks import add
result = add.delay(5,5)
task_id = result.task_id
E in un altro processo se uso lo stesso 'task_id' (copiato e incollato ad un altro REPL, o in una richiesta HTTP diverso) in questo modo:
from celery.result import AsyncResult
result = AsyncResult(id="copied_task_id", backend="db+mysql://u:[email protected]/db")
result.get() # AttributeError: 'str' object has no attribute 'get_task_meta'
result.state # AttributeError: 'str' object has no attribute 'get_task_meta'
result.status # AttributeError: 'str' object has no attribute 'get_task_meta'
E in un altro processo, se faccio:
from task import add # in this instance I know that an add task was performed
result = add.AsyncResult(id="copied_task_id")
result.status # "SUCCESSFUL"
result.state # "SUCCESSFUL"
result.get() # 10
mi piacerebbe essere in grado di ottenere il risultato senza sapere prima mano ciò che compito sta generando il risultato. Nel mio ambiente reale ho intenzione di restituire questo task_id al client e lasciare che interrogino lo stato del loro lavoro tramite una richiesta HTTP.
Esattamente quello che stavo cercando; Condivido il tuo punto di vista sul fatto che questo è molto poco chiaro dalla documentazione, quindi il tuo post mi ha aiutato molto. – markjan
È possibile che si desideri impostare un piccolo timeout per questa chiamata, poiché alcune chiamate 'get' di Celery potrebbero non tornare per un tempo molto lungo in caso di ID di attività non valido o un'attività che non è più nota al broker. Vedi http://stackoverflow.com/a/10074280/992887 – RichVel
Grazie per questa correzione. Mi ha fatto tirare i capelli per 2 settimane. – Pant