Flask asyncio 异步处理请求

1,134 阅读1分钟

来自:

​​​​​​Making Flask async and Quart sync (pgjones.dev)

示例:

from flask import Flask, jsonify, has_request_context, copy_current_request_context, request
from functools import wraps
from concurrent.futures import Future, ThreadPoolExecutor
import asyncio

def run_async(func):
    @wraps(func)
    def _wrapper(*args, **kwargs):
        call_result = Future()
        def _run():
            loop = asyncio.new_event_loop()
            try:
                result = loop.run_until_complete(func(*args, **kwargs))
            except Exception as error:
                call_result.set_exception(error)
            else:
                call_result.set_result(result)
            finally:
                loop.close()
 
        loop_executor = ThreadPoolExecutor(max_workers=1)
        if has_request_context():
            _run = copy_current_request_context(_run)
        loop_future = loop_executor.submit(_run)
        loop_future.result()
        return call_result.result()
 
    return _wrapper



@app.route("/process/report/success/", methods=["POST"])
@run_async
async def report_result_success():
    account = request.json
    print(request.json)
    debug('>> 注册成功: ' + str(account))
    write_csv(account, '成功.csv')
    return Result.ok()

水话:

        像Flask这样的Web框架是异步编程技术的完美用例,因为它们的目的是处理独立的无状态请求。此外,Web框架通常由IO而不是CPU工作主导,这使得它们成为异步事件循环的明显用例。

        因此,Flask 通常与线程或事件循环一起使用。具体来说,非异步等待事件循环实现、eventlet、gevent 和 meinheld。异步解决方案之间的这种选择对 Flask 代码的影响非常小。

        Flask自成立以来一直处于同步状态,并且大量公司以这种方式成功地在生产中运行它。然而,Python已经在标准库中发展并正式化了一个基于异步等待的事件循环,即asyncio,社区又增加了两个Curio和Trio。这些基于异步等待的事件循环需要更改代码才能与事件循环交互