Flask重定向或从嵌套视图函数返回数据

时间:2019-09-15 20:32:38

标签: python multithreading flask python-multithreading

我正在尝试从GET请求的视图运行代码。此代码在新线程中执行,因为它需要一些时间才能运行。请注意,我没有加入线程,因为那样会导致视图挂起。

我试图从内部do_work函数重定向回到“ / task”路由,但是没有成功。我是否可以通过重定向将这些数据获取到视图中?我可以使用ajax请求来帮助我吗?

此视图当前设计的缺点是什么?

@app.route("/task", methods=["GET"])
def start_task():
    def do_work(value):
        import time; time.sleep(value)
        return "finished"

    thread = Thread(target=do_work, kwargs={'value': 5})
    thread.start()
    return "started"

1 个答案:

答案 0 :(得分:0)

如果您想使用Python threading模块,请使用以下解决方案:

import threading
from flask import Flask, jsonify

app = Flask(__name__)

tasks = []
results = []

def do_work(value, task_id, results):
    import time; time.sleep(value)
    results[task_id] = "finished task {}".format(task_id)

@app.route("/task", methods=["GET"])
def start_task():
    new_task_id = len(tasks)
    task = threading.Thread(target=do_work, kwargs={'value': 5, 'task_id': new_task_id, 'results': results})
    task.start()
    tasks.append(task)
    results.append(None)
    return jsonify({'task_id': new_task_id, 'total_tasks': len(tasks)})


@app.route("/task/<int:task_id>", methods=["GET"])
def task_status(task_id):
    assert 0 <= task_id < len(tasks)
    if tasks[task_id].is_alive():
        return jsonify({'status': 'running'})
    try:
        tasks[task_id].join()
        return jsonify({'status': 'finished', 'result': results[task_id]})
    except RuntimeError:
        return jsonify({'status': 'not started'})


if __name__ == '__main__':
    app.run(host='0.0.0.0')

由于Thread.join()不返回值,因此我使用了线程和结果列表的概念 这个answer

此代码为每个任务创建一个端点。任务总数和新任务ID返回 JSON,因此您可以更轻松地利用AJAX。

但是要注意 Global Interpreter Lock 这使得所有Python线程都在单个内核上运行。一个更好的解决方案是使用 multiprocessing模块,特别是Pool类(请参见此answer)。