我想完成这样的事情:
results = []
for i in range(N):
data = generate_data_slowly()
res = tasks.process_data.apply_async(data)
results.append(res)
celery.collect(results).then(tasks.combine_processed_data())
即在很长一段时间内启动异步任务,然后安排一个只有在所有早期任务完成后才会执行的依赖任务。
我查看了chain
和chord
之类的内容,但看起来它们只有在您可以完全预先构建任务图时才有效。
答案 0 :(得分:1)
对于任何有兴趣的人,我最终都使用了这个代码段:
@app.task(bind=True, max_retries=None)
def wait_for(self, task_id_or_ids):
try:
ready = app.AsyncResult(task_id_or_ids).ready()
except TypeError:
ready = all(app.AsyncResult(task_id).ready()
for task_id in task_id_or_ids)
if not ready:
self.retry(countdown=2**self.request.retries)
编写工作流程就像这样:
task_ids = []
for i in range(N):
task = (generate_data_slowly.si(i) |
process_data.si(i)
)
task_id = task.delay().task_id
task_ids.append(task_id)
final_task = (wait_for(task_ids) |
combine_processed_data.si()
)
final_task.delay()
答案 1 :(得分:0)
这样你就可以同步运行你的任务了。
解决方案完全取决于收集data
的方式和位置。粗略地说,鉴于generate_data_slowly
和tasks.process_data
是同步的,更好的方法是将两者加入task
(或chain
}和group
chord
将允许您向group
添加回调。
最简单的例子是:
from celery import chord
@app.task
def getnprocess_data():
data = generate_data_slowly()
return whatever_process_data_does(data)
header = [getnprocess_data.s() for i in range(N)]
callback = combine_processed_data.s()
chord(header)(callback).get()