繁体   English   中英

完成所有任务后运行任务

[英]Running a task after all tasks have been completed

我正在编写一个需要并行运行一系列任务的应用程序,然后运行所有任务结果的单个任务:

@celery.task
def power(value, expo):
    return value ** expo

@celery.task
def amass(values):
    print str(values)

这是一个非常人为和过于简单的例子,但希望这一点很好。 基本上,我有许多需要通过power ,但我只想对所有任务的结果进行amass 所有这些都应该是异步发生的,而且我不需要从amass方法中获得任何回报。

有没有人知道如何在芹菜中设置它,以便一切都是异步执行的,并且在完成所有操作后调用带有结果列表的单个回调?

正如亚历山大·阿法纳西耶夫所建议的那样,我已经设置了这个例子来chord一起运行:

from time import sleep

import random

tasks = []

for i in xrange(10):
    tasks.append(power.s((i, 2)))
    sleep(random.randint(10, 1000) / 1000.0) # sleep for 10-1000ms

callback = amass.s()

r = chord(tasks)(callback)

不幸的是,在上述例子中,所有任务tasks启动,只有当chord方法被调用。 有没有办法让每个任务可以单独启动,然后我可以添加一个回调到组,以便在一切都完成后运行?

这是一个适用于我的目的的解决方案:

tasks.py

from time import sleep

import random

@celery.task
def power(value, expo):
    sleep(random.randint(10, 1000) / 1000.0) # sleep for 10-1000ms
    return value ** expo

@celery.task
def amass(results, tasks):
    completed_tasks = []
    for task in tasks:
        if task.ready():
            completed_tasks.append(task)
            results.append(task.get())

    # 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

使用案例:

tasks = []

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

amass.delay([], tasks)

应该做的是尽快异步启动所有任务。 一旦他们全部被发布到队列中, amass任务也将被发布到队列中。 amass任务将继续重新发布,直到所有其他任务完成。

Celery为您可以想象的大多数工作流程提供了大量工具

看来你需要使用和弦 这是文档的引用:

和弦就像一个群体,但有一个回调。 和弦由标题组和正文组成,其中正文是在标题中的所有任务完成后应执行的任务。

从你的问题看一下这个片段,看起来你传递一个list作为和弦标题,而不是一个group

from time import sleep
import random

tasks = []

for i in xrange(10):
    tasks.append(power.s((i, 2)))
    sleep(random.randint(10, 1000) / 1000.0) # sleep for 10-1000ms

callback = amass.s()

r = chord(tasks)(callback)

list转换为group应该会导致您期望的行为:

...

callback = amass.s()

tasks = group(tasks)

r = chord(tasks)(callback)

@ alexander-afanasiev给你的答案基本上是正确的:使用和弦。

你的代码没问题,但tasks.append(power.s((i, 2)))实际上并没有执行子任务,只是将子任务添加到列表中。 它是chord(...)(...) ,它发送尽可能多的消息给代理作为您在tasks列表中定义的子tasks ,再加上一个用于回调子任务的消息。 当你打电话给chord时,它会尽快返回。

如果您想知道和弦何时结束,您可以使用样本中的r.ready()查询完成,例如使用单个任务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM