使用带有asyncio的gunicorn时如何屈服于另一个请求?

Der*_*wok 10 python django gunicorn python-asyncio

我正在尝试使用我正在使用以下命令开发的Django应用程序使用Gunicorn中的gaiohttp工作程序:

gunicorn -k gaiohttp -b localhost:8080 myproject.wsgi
Run Code Online (Sandbox Code Playgroud)

我的最终目标是能够同时处理请求 - 即让1名gunicorn工作者同时处理多个请求.有I/O绑定操作使这些请求变慢.

我知道当我处理请求时,事件循环已经在运行:

class MyView(View):

    def get(self, request):
        loop = asyncio.get_event_loop()
        loop.is_running() # True
        ...
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 如何yield from asyncio.sleep(10)在视图代码中执行操作?

    class MyView(View):
    
        def get(self, request):
            # Raises AssertionError: yield from wasn't used with future
            yield from asyncio.sleep(10)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我可以向事件循环添加任务,但是在处理请求时它们不会阻塞

    @asyncio.coroutine
    def simulate_work():
        yield from asyncio.sleep(10)
    
    class MyView(View):
    
        def get(self, request):
            # This runs simulate_work(), however, it doesn't block 
            # the response is returned before simulate_work() is finished
            loop = asyncio.get_event_loop()
            task = loop.create_task(simulate_work())
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我尝试使用期货,但事件循环已经在运行

    @asyncio.coroutine
    def simulate_work(future):
        yield from asyncio.sleep(10)
        future.set_result('Done!')
    
    class MyView(View):
    
        def get(self, request):
            future = asyncio.Future()
            asyncio.async(simulate_work(future))
            loop = asyncio.get_event_loop()
            # Raises RuntimeError: Event loop is running.
            loop.run_until_complete(future)
            print(future.result())
    
    Run Code Online (Sandbox Code Playgroud)

很显然,我对asyncio或gaiohttp并不了解.

如何asyncio.sleep(10)阻止当前请求,但不能阻止gunicorn处理其他请求?

And*_*lov 6

抱歉,您无法从您的wsgi应用程序调用协同程序 - WSGI是同步协议,以及构建在它之上的框架(Django,Flask,Pyramid).

我已经实现了gaiohttp工作者,但它是asyncio世界的二等公民.如果您确实需要异步HTTP服务器,请尝试aiohttp.web.