为什么Celery只运行链中的第一个任务?

时间:2016-04-09 08:39:31

标签: django celery chain

我有一个工作链,但是当我添加baseURL: "/", defaultJSExtensions: true, transpiler: "typescript", typescriptOptions: { "module": "commonjs", "emitDecoratorMetadata": true }, packages: { "app": { "main": "main", "defaultExtension": "ts" } }, 时,它只执行第一个任务。

apply_async()

使用链式命令:

@task(name='run_a', delay=True)
def run_a(**kwargs):
    do_whatever(kwarg['var'])
    return

@task(name='run_b', delay=True)
def run_b(**kwargs):
    # ...
    return

@task(name='run_c', delay=True)
def run_c(**kwargs):
    # ...
    return
  • 如果没有ret = chain( run_a.s(**kwargs), run_b.s(**kwargs), run_b.s(**kwargs) ).apply_async() ,它将按预期工作(同步)。
  • ' kwargs'是一个字典。

2 个答案:

答案 0 :(得分:0)

虽然Celery在执行前验证了您的任务,但是要使func工作*args**kwargs

# Kwargs was filled, I added an empty args list
args = []
kwargs = {
    'some': 'intelligent data',
    }

使用两者调用函数时,它按预期工作:

ret = chain(
    run_a.s(*args, **kwargs),
    run_b.s(*args, **kwargs),
    run_b.s(*args, **kwargs)
).apply_async()

答案 1 :(得分:0)

基于http://docs.celeryproject.org/en/master/userguide/canvas.html#chains上的文档:将应用链接的任务,并将其父任务的结果作为第一个参数。。因此,要强制下一个链接的任务不要将父结果用作参数,我们必须使用.si()快捷方式使该任务不可变。所以我们必须重新编写链,如下所示:

In [29]: ret = chain(
    ...:     run_a.si(**kwargs),
    ...:     run_b.si(**kwargs),
    ...:     run_c.si(**kwargs)
    ...: ).apply_async()

结果

In [30]: print ret.parent.parent.graph
0e1541f8-93c2-48c9-95b0-7a0a5971d74a(1)
     7b5e11e4-6ccf-49cc-a1dd-42bf407a37de(0)
7b5e11e4-6ccf-49cc-a1dd-42bf407a37de(0)
70a6e66c-1ef9-4814-ae23-9c905ee1fcd5(2)
     0e1541f8-93c2-48c9-95b0-7a0a5971d74a(1)
          7b5e11e4-6ccf-49cc-a1dd-42bf407a37de(0)