Làm cách nào để kéo kết quả của tác vụ nếu tôi không biết trước đó tác vụ nào đã được thực hiện? Dưới đây là các thiết lập: Với nguồn sau ('tasks.py'):Lấy kết quả từ 'task_id' trong Celery từ tác vụ không xác định
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
với RabbitMQ 3.3.2 chạy cục bộ:
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.
với cần tây 3.1.12 chạy cục bộ:
-------------- [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
Sau đó tôi có thể nhập phương thức và truy xuất kết quả bằng '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
Trong ví dụ tiếp theo, tôi chia các bước này giữa các quy trình. Trong một quá trình tôi lấy 'task_id' như vậy:
from tasks import add
result = add.delay(5,5)
task_id = result.task_id
Và trong quá trình khác nếu tôi sử dụng cùng một 'task_id' (sao chép và dán khác REPL, hoặc trong một yêu cầu HTTP khác nhau) như vậy:
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'
Và trong quá trình khác nếu tôi làm:
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
tôi muốn để có thể nhận được kết quả mà không cần biết trước khi tay những gì nhiệm vụ được tạo ra kết quả. Trong môi trường thực của tôi, tôi dự định trả lại task_id này cho máy khách và cho phép họ truy vấn trạng thái công việc của họ thông qua một yêu cầu HTTP.
Chính xác những gì tôi đang tìm kiếm; Tôi chia sẻ quan điểm của bạn rằng điều này là rất không rõ ràng từ các tài liệu để bài viết của bạn đã giúp tôi rất nhiều. – markjan
Bạn có thể muốn thiết lập một thời gian chờ nhỏ trên cuộc gọi này, bởi vì một số cuộc gọi 'có thể' của Celery có thể không trả lại trong một thời gian rất dài trong trường hợp ID nhiệm vụ không hợp lệ hoặc một tác vụ không còn được người môi giới biết đến. Xem http://stackoverflow.com/a/10074280/992887 – RichVel
Cảm ơn bạn đã sửa lỗi này. Nó khiến tôi kéo tóc trong 2 tuần. – Pant