aiohttp处理程序中的后台任务

时间:2018-09-11 12:59:53

标签: python python-asyncio aiohttp

我正在尝试在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

我想念的是什么?

1 个答案:

答案 0 :(得分: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),
]