所有其他任务完成后,需要启动芹菜任务

时间:2017-10-31 06:14:30

标签: python-2.7 celery

我对芹菜比较新。我要求我的芹菜任务之一应该在所有其他任务完成后启动。我确实玩过它并且还在网上发现了一些文档,其中表明我应该使用groupschords等我完全无法理解的内容。

我还发布了另一个SO here的问题,但到目前为止还没有找到任何令人信服的答案。

最后我遇到了this SO question,我可以清楚地(至少从概念上)理解接受的答案中发生了什么。但是,当我尝试复制完全相同的程序时,它抛出了以下错误:

EncodeError: <AsyncResult: cf5875f1-7f72-449c-9808-07c9c9459737> is not JSON serializable

我在上述问题的评论中也发布了同样的问题,这个问题似乎很老,因此到目前为止我的评论还没有得到任何关注。

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

如果

您已经有一个必须一个接一个地执行的任务列表,并希望合并您只能使用chords的结果。

else

如果您继续向celery添加任务(而不是立即执行),并且您希望逐个执行它们,那么只需设置1个并发= 1的工作程序即可实现此目的,任务只能通过串行执行。

我也遇到了并行执行问题,我通过在开始时运行一个并发= 1的worker来解决它,但后来我使用redis锁定机制来实现解决方法。

答案 1 :(得分:0)

this SO answer中接受的答案实际上帮助我实现了我想要的目标。 (这可能是一种hacky方式,但它解决了我的问题)。然而答案却产生了错误:

EncodeError: <AsyncResult: cf5875f1-7f72-449c-9808-07c9c9459737> is not JSON serializable

我能够解决如下(我在答案的评论中也提到了这一变化)

所以在答案中的用例部分:

tasks = []
for i in xrange(10):
    tasks.append(power.delay(i, 2))

amass.delay([], tasks)

作为amass.delay()的第二个参数,我们传递一个任务对象列表。我只是将其更改为实际传递任务ID列表。所以amass()现在看起来像:

tasks = []
for i in xrange(10):
    x = power.delay(i, 2)
    tasks.append(x.id)

amass.delay([], tasks)

并在amass()中进行了相应的更改,如下所示 它解决了错误并完成了我想要实现的工作。

@celery.task()
def amass(results, tasks):
    completed_tasks = []
    for task_id in tasks:
        result = AsyncResult(task_id, app=celery)
        if result.ready():
            completed_tasks.append(task_id)
            #results.append(task.get()) did not need this so commented it out

    # remove completed tasks
    tasks = list(set(tasks) - set(completed_tasks))

    if len(tasks) > 0:
        # resend the task to execute at least 1 second from now
        amass.delay(results, tasks, countdown=1)
    else:
        # we done
        print results