Python 芹菜-异步任务链

Python 芹菜-异步任务链,python,asynchronous,flask,redis,celery,Python,Asynchronous,Flask,Redis,Celery,我正在尝试开发一个概念证明,以支持使用芹菜和redis作为代理的异步任务链接 该程序是Flask API,带有/run和三个需要作为异步任务运行的函数,例如return from a(),是b()的参数,return b()是c()的参数,c()通过集合对象“collection”将数据写入mongodb集合 @celery.task def a(param): print("Original: {0}".format(param)) print("Inside Task 1")

我正在尝试开发一个概念证明,以支持使用芹菜和redis作为代理的异步任务链接

该程序是Flask API,带有/run和三个需要作为异步任务运行的函数,例如return from a(),是b()的参数,return b()是c()的参数,c()通过集合对象“collection”将数据写入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(),它首先等待整个数据在a()中排队,然后才执行b()。我需要的是,任何任务a()一旦执行,就应该将其交给b(),以此类推。。
有人对我的错误有什么指点吗?

从您提供的描述中,听起来您应该使用一个。链完全按照您的要求执行,将任务集中在一起,将每个任务的返回值传递给链中的下一个任务。

我可能遗漏了一些内容,但最简单的方法似乎是在上一个任务结束时调用下一个任务

@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)

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

Hey@MrName,是的!正如你在代码中看到的,我使用了chain。我面临的问题是无法控制以何种顺序执行哪项任务。例如,为函数a()生成了三个id为a1、a2、a3等的任务,并且可能会生成多达a20的任务,如果任务a2成功,我需要任务控制为函数b()生成一个任务b2。有没有办法理解控制是如何流动的?啊,我明白了,这是有道理的。抱歉,没有注意到代码中的
链调用。好问题,看看我能不能想出什么有用的办法。在后台工作中产生后台任务正常吗?虽然它似乎确实提供了对流程流的控制,但如果b()是长时间运行的任务,它似乎不是非常有效,它也将绑定运行任务a()的流程id,对于c()也是如此。这难道不意味着当任务a完成时,芹菜不能发出完成信号并继续占用资源吗?不,如果在任务内调用apply_async()和在任务外调用apply_async()具有相同的效果-它会向任务队列发送一条消息,以便在下一个可用工作线程上安排作业。这意味着您不能使用“a”的结果来跟踪“c”的完成情况,如果您依赖芹菜结果api,则必须传回生成任务的任务id。(然而,我也从未使用过results api,而是依赖于日志记录和数据存储中的任务生成的信号)上述过程对我来说很有效,解决了问题。