我们说我有以下芹菜代码:
from celery import Celery, group
app = Celery()
app.conf.update(
broker_url=some_broker,
result_backend=some_backend,
)
@app.task
def generate_list(n):
return list(range(n))
@app.task
def double_it(value):
return value * 2
@app.task
def tsum(value):
return sum(value
创建一个产生异步结果的组或和弦很容易产生实际结果:
>>> group([double_it.s(x) for x in range(5)])().get()
[0, 2, 4, 6, 8]
>>> (group([double_it.s(x) for x in range(5)]) | tsum.s())().get()
20
但是,我无法弄清楚如何使用任意大小的列表执行类似操作,而不会使部件同步。我试过这个:
>>> @app.task
... def make_group(items):
... return group([double_it.s(x) for x in items])()
>>> @app.task
... def make_chord(items):
... return chord(
... [double_it.s(x) for x in items],
... tsum.s(),
... )()
>>> (generate_list.s(5) | make_group.s())().get()
['5d23a31f-6da3-4fec-8bd0-6e57a4da9c43',
[[['7d2cf535-96d6-40fe-b76b-d118aaffbc95', None], None],
[['5ef96f17-8ac7-4c1b-a794-c0e6e85c2b8c', None], None],
[['ec595134-76af-40e8-a211-d2592acd250f', None], None],
[['146b0da2-c9bf-49c3-a259-a98808c2b1af', None], None],
[['9ad3eb4a-92e2-4194-ae9f-3aa17dbf0333', None], None]]]
>>> (generatelist.s(5) | make_chord.s())().get()
[['045a5130-cc33-4ba7-99cc-58dd94675515',
['771f444a-2df5-4436-96e0-6e1774c2b437',
[[['4b88c20c-f5ac-485e-aae8-b562c5865cd5', None], None],
[['b5890545-48eb-49d9-8a5b-d638381ce3ab', None], None],
[['e8f19456-5b29-4d2f-b8e2-d81cb9f1c258', None], None],
[['aa95ba0f-04d3-4bc1-a34a-905076fe4cb7', None], None],
[['155f2183-e673-4921-be4e-568b5011b1e9', None], None]]]],
None]
...它似乎在一个包含一堆None
s的奇怪嵌套列表中返回各种任务ID。尝试制作和弦会导致无法JSON序列化GroupResult
的错误,这可能是因为make_group
正在立即返回并继续执行下一个任务而不是正在构建的和弦。明确地制作和弦(而不是隐含地使用组 - >任务链)可以消除错误,但您仍然可以使用任务ID立即返回。
我想通过解决这个问题的唯一方法是等待链的结果,然后使用任务ID为正确的任务创建异步结果。
>>> from celery.result import AsyncResult
>>> task_id = (generate_list.s(5) | make_chord.s())().get()[0][0]
>>> AsyncResult(task_id).get()
20
如果不依靠获取相应的任务ID然后从中创建AsyncResult
,您应该如何完成这项工作?