芹菜 - 异步任务链

时间:2018-01-15 11:08:15

标签: python asynchronous flask redis celery

我正在尝试为使用celery和redis作为代理的异步任务链开发一个概念验证。

该程序是带有/ run的Flask API和需要作为异步任务运行的三个函数,这些函数从a()返回,是b()的参数,返回b()是c()的参数,用于写入数据通过集合对象'收集mongodb集合。

@celery.task
def a(param):
    print("Original: {0}".format(param))
    print("Inside Task 1")
    param.update({"timestamp_A":str(datetime.timestamp), "result_A":True})
    print(param)
    return param

@celery.task
def b(param):
    print("Inside Task 2")
    param.update({"timestamp_B":str(datetime.timestamp), "result_B":True})
    print(param)
    return param

@celery.task
def c(param):
    print("Inside Task 3")
    collection.insert(dict(param))
    print("Output Saved to DB")


@app.route('/run', methods = ['GET'])
def run():
    if request.method != 'GET':
        return "HTTP Method not allowed"

    if request.method == 'GET':
        T = 1000
        for num in range(0, T):
            ds = {"test": num}
            chain(a.s(ds) | b.s() | c.s()).apply_async()
        return "Process Complete"

if __name__ == '__main__':
    app.run(debug=True)

使用上面的代码任务链接工作,即a()用它的参数执行,但是对于函数b()来执行它等待整个数据先在()中排队,然后才执行b()。我需要尽快完成任务a()执行它应该交给b()等等。 任何人都有关于我可能出错的地方的任何指示?

2 个答案:

答案 0 :(得分:0)

根据您提供的说明,听起来您应该使用chain。链完全符合您的要求,将任务整合在一起,将每个任务的返回值传递给链中的下一个任务。

答案 1 :(得分:0)

我可能会遗漏一些东西,但似乎最简单的方法就是在上一个任务结束时调用下一个任务。

@celery.task
def a(arg):
  ret = calc(arg)
  b.apply_async(ret)

@celery.task
def b(arg):
  ret = calc(arg)
  c.apply_async(ret)

@celery.task
def c(arg):
  ret = calc(arg)
  mongo.store(ret)

这不允许你有时在循环中调用a,有时不会,但你可以将任务包装在同步运行内部部分的外部任务中。