aiohttp slowness with threading

假装没事ソ 提交于 2020-01-24 14:08:05

问题


I copied the code from How to run an aiohttp server in a thread?. It runs fine. So I am adding one second sleep. When I launch 10 requests at the same time. The average response time is 9 seconds. Why is that? Wouldn't all requests coming back in a little bit over 1 second?

import asyncio
import threading
from aiohttp import web
import time

loop = asyncio.get_event_loop()


def say_hello(request):
    time.sleep(1)
    return web.Response(text='Hello, world')


app = web.Application(debug=True)
app.add_routes([web.get('/', say_hello)])

handler = app.make_handler()
server = loop.create_server(handler, host='127.0.0.1', port=8080)


def aiohttp_server():
    loop.run_until_complete(server)
    loop.run_forever()


t = threading.Thread(target=aiohttp_server)
t.start()

回答1:


Use asyncio.sleep instead. Your setup is running coros that hard sleep 1 second before they yield to the event loop. So if you gather a bunch of them you have to wait that 1 second for each one serially.




回答2:


You are starting the server in a second thread, but all of the requests are served from the same thread. The call to time.sleep blocks this thread and does not yield to the event loop so that the requests are effectively processed serially.

If you genuinely want to use sleep for a delay in the response you could use asyncio.sleep instead, which yields to the event loop.

However I expect you are using it as a placeholder for another blocking function. In this case you need to run this in another thread to the main server. The example below shows how to do this using run_in_executor and asyncio.wait.

import asyncio
from aiohttp import web
from concurrent.futures import ThreadPoolExecutor
import time


def blocking_func(seconds: int) -> int:
    time.sleep(seconds)
    return seconds


async def view_page(request: web.Request):
    seconds = int(request.query.get("seconds", 5))
    executor = request.app["executor"]
    loop = asyncio.get_event_loop()
    task = loop.run_in_executor(executor, blocking_func, seconds)
    completed, pending = await asyncio.wait([task])
    result = task.result()
    return web.Response(text=f"Waited {result} second(s).")


def create_app():
    app = web.Application()
    app.add_routes([web.get("/", view_page)])
    executor = ThreadPoolExecutor(max_workers=3)
    app["executor"] = executor
    return app


if __name__ == "__main__":
    app = create_app()
    web.run_app(app)


来源:https://stackoverflow.com/questions/55133510/aiohttp-slowness-with-threading

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!