我正在使用来自webapp的Celery来启动任务层次结构。
我正在使用以下任务:
task_a
task_b
task_c
notify_user
Django视图启动了几个task_a
个实例。他们每个人都进行一些处理,然后启动几个task_b
个实例。每个都进行一些处理,然后启动几个task_c
个实例。
要想象:
我的目标是执行所有任务,并在整个层次结构完成后立即运行回调函数。此外,我希望能够将数据从最低级别的任务传递到顶级。
notify_user
回调函数。notify_user
回调函数需要访问task_c
s。所有任务都应该是非阻止的,因此task_b
不应等待所有task_c
子任务完成。
实现上述目标的正确方法是什么?
答案 0 :(得分:4)
该解决方案最终成为此拉取请求中提供的动态任务功能:https://github.com/celery/celery/pull/817。这样,每个任务都可以返回一组子任务,然后替换队列中的原始任务。
答案 1 :(得分:1)
假设您有以下任务:
celery = Celery(
broker="amqp://test:test@localhost:5672/test"
)
celery.conf.update(
CELERY_RESULT_BACKEND = "mongodb",
)
@celery.task
def task_a(result):
print 'task_a:', result
return result
@celery.task
def task_b(result):
print 'task_b:', result
return result
@celery.task
def task_c(result):
print 'task_c:', result
return result
@celery.task
def notify_user(result):
print result
return result
对于给定的输入数据(如您所绘制的):
tree = [
[["C1", "C2", "C3"], ["C4", "C5"]], [["C6", "C7", "C8"], ["C9"]]
]
你可以这样做:
a_group = []
for ia, a in enumerate(tree):
print "A%s:" % ia
b_group = []
for ib, b in enumerate(a):
print " - B%s:" % ib
for c in b:
print ' -', c
c_group = group([task_c.s(c) for c in b])
b_group.append(c_group | task_b.s())
a_group.append(group(b_group) | task_a.s())
final_task = group(a_group) | notify_user.s()
它的代表是(不读它,它很丑:)
[[[__main__.task_c('C1'), __main__.task_c('C2'), __main__.task_c('C3')] | __main__.task_b(), [__main__.task_c('C4'), __main__.task_c('C5')] | __main__.task_b()] | __main__.task_a(), [[__main__.task_c('C6'), __main__.task_c('C7'), __main__.task_c('C8')] | __main__.task_b(), [__main__.task_c('C9')] | __main__.task_b()] | __main__.task_a()] | __main__.notify_user()
传递给notify_user的数据是:
[[['C1', 'C2', 'C3'], ['C4', 'C5']], [['C6', 'C7', 'C8'], ['C9']]]
所有内容都通过回调(和弦)运行,因此没有任务等待其他任务。