在所有任务完成之前执行芹菜和弦

时间:2014-09-26 14:42:32

标签: python django celery django-celery

我有一堆可以同时执行的任务,但是一旦一切准备就绪,我想执行最后一项。我使用以下代码:

chunk_tasks = []
for index, chunk in enumerate(chunks):
    chunk_tasks.append(import_chunk.s(meta.pk))

g = group(chunk_tasks)
chord(g)(import_completed.s(meta.pk, max_lines=max_lines))

但是看起来import_completed在所有任务完成之前执行。 import_chunk任务也是如此:

@task(bind=True, ignore_result=IGNORE_RESULTS)
def import_chunk(self, meta_pk):
    try:
        # do some stuff
    except Exception, e:
        if self.max_retries == self.request.retries:
            logger.exception('Unexpected error in import_chunk')
        raise self.retry(countdown=60, max_retries=3)

所以问题是我做错了什么?

1 个答案:

答案 0 :(得分:0)

Chord是一项仅在组中的所有任务完成执行后才执行的任务。因此,需要在其标头中执行任务状态以进行同步。

但是当您将ignore_result设置为task时,工作人员将不会存储任务状态并返回此任务的值。

这将导致根据您的工作流程重试任务或抛出异常或任何故障。

因此,chord(add.s(i, i) for i in range(10))(tsum.s()).get()完全有效并为CASE 1提供结果,但它给CASE 2带来了一些麻烦。

案例1:

@app.task
def add(x, y):
    return x + y

@app.task
def tsum(numbers):
    return sum(numbers)

案例2:

@app.task(ignore_result=True)
def add(x, y):
    return x + y

@app.task(ignore_result=True)
def tsum(numbers):
    return sum(numbers)

因此,您必须更改ignore_result或更改任务的工作流程。

来自docs:

你应该尽可能避免使用和弦。尽管如此,和弦是您工具箱中的强大原语,因为同步是许多并行算法的必需步骤。