安排Celery任务在其他任务完成后运行

时间:2017-01-18 21:59:09

标签: celery

我想完成这样的事情:

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())

即在很长一段时间内启动异步任务,然后安排一个只有在所有早期任务完成后才会执行的依赖任务。

我查看了chainchord之类的内容,但看起来它们只有在您可以完全预先构建任务图时才有效。

2 个答案:

答案 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_slowlytasks.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()