aiohttp处理程序中的后台任务

问题描述 投票:0回答:1

我正在尝试在aiohttp处理程序中启动后台长时间任务:

from aiohttp import web
import time
import asyncio


async def one(request):
    print("Start")
    loop = asyncio.get_event_loop()
    tasks = [
        asyncio.ensure_future(long_computation(1)),
        asyncio.ensure_future(long_computation(2)),
    ]
    done, _ = loop.run_until_complete(asyncio.wait(tasks))

    for f in done:
        print(f"{f.result()}")

    return web.Response(text="one")


async def long_computation(id: int):
    print(f"run long computation with delay: {id}")
    time.sleep(id)
    print(f"done long computation with delay: {id}")


app = web.Application(client_max_size=1024 * 1024 * 10)
app.add_routes([web.get('/one', one)])

web.run_app(app)

但得到一个错误:

Error handling request
Traceback (most recent call last):
  File "env/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 378, in start
    resp = await self._request_handler(request)
  File "env/lib/python3.6/site-packages/aiohttp/web_app.py", line 341, in _handle
    resp = await handler(request)
  File "test_async.py", line 13, in one
    done, _ = loop.run_until_complete(asyncio.wait(tasks))
  File "/usr/lib/python3.6/asyncio/base_events.py", line 455, in run_until_complete
    self.run_forever()
  File "/usr/lib/python3.6/asyncio/base_events.py", line 409, in run_forever
    raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
run long computation with delay: 1
done long computation with delay: 1
run long computation with delay: 2
done long computation with delay: 2

我缺少什么?

python python-asyncio aiohttp
1个回答
2
投票

你需要替换:

done, _ = loop.run_until_complete(asyncio.wait(tasks))

有:

done, _ = await asyncio.wait(tasks)

此外,如果long_computation阻塞,你需要使用run_in_executor将其交给一个单独的线程:

loop = asyncio.get_event_loop()
tasks = [
    loop.run_in_executor(None, long_computation, 1),
    loop.run_in_executor(None, long_computation, 2),
]
© www.soinside.com 2019 - 2024. All rights reserved.