将任务结果输入Celery中的地图

时间:2018-09-28 09:51:36

标签: python celery

我觉得这是一个非常简单的用例,但不是我从文档中成功解决过的一个用例。

这是我的问题的人为设计版本:

我有一个带有单个参数并返回列表的任务。我想对列表中的每个元素应用另一个任务。然后,我(视情况而定)可能要继续处理其他任务。

chain(
    my.tasks.divide.s(data),
    my.tasks.conquer.map(),
    ).apply_async().get()

chain(
    my.tasks.divide.s(data),
    my.tasks.conquer.map(),
    my.tasks.unite.s(),
    my.tasks.rule.s(),
    ).apply_async().get()

地图无法正常工作,但我认为应该!我只想从一个参数链接到一个列表,然后再返回。.当然,这样做并不难吗?

“解决方案” herehere似乎过于复杂,我不认为这是最佳实践。

The documentation在和弦,地图和链条上无济于事。

编辑:到目前为止,我已经掌握了。这里的问题是我必须两次调用.apply_async().get()才能获得实际结果,因为中间步骤返回的和弦不是实际结果:

@app.task()
def divide(item):
    return [x for x in item]

@app.task()
def conquer(item):
    return item.upper()

@app.task()
def rule(items):
    return "".join(items)

@app.task()
def conquer_group(items):
    return group([conquer.s(x) for x in items])

@app.task()
def rule_group(items):
    return chord([conquer.s(x) for x in items], rule.s())

def main():
    print chain(
        divide.s("foobarbaz"),
        rule_group.s(),
        ).apply_async().get().apply_async().get()

1 个答案:

答案 0 :(得分:0)

这里的问题是map()需要一个可迭代的实例化。 这就是为什么人们可以执行(sample.map(range(100)) | another_task.s()).apply_async()但不能实例化接受链中最后一个任务的结果的map()签名的原因。 我认为,执行此操作的简单方法是在任务中实例化map()签名。

@app.task()
def divide(item):
    return [x for x in item]

@app.task()
def conquer(item):
    return item.upper()

@app.task()
def process(items):
    return conquer.map(items)

def run():
    (divide.s("foobar") | process.s()).apply_async()