在运行时清理asyncio all_tasks()

时间:2019-07-02 22:24:10

标签: python asyncio

我有一个aiohttp应用程序,并且一个请求引发了一个(假的!)异常:

ERROR:aiohttp.server:Error handling request
Traceback (most recent call last):
  File "C:\Program Files\Python36\lib\site-packages\aiohttp\web_protocol.py", line 418, in start
    resp = await task
  File "C:\Program Files\Python36\lib\site-packages\aiohttp\web_app.py", line 458, in _handle
    resp = await handler(request)
  File "webservice.py", line 60, in handle_status
    raise ValueError('*******************')

我等待〜2分钟,然后通过CTRL + C关闭应用程序。这将引发一个“ KeyboardInterrupt”。在异常处理程序中,将运行以下代码。

def close_loop(loop):
    """ Gracefully close down the event loop.
    """
    # Log any excepting tasks using the usual logging module.
    tasks = asyncio.Task.all_tasks(loop=loop)
    exceptions = [(task, task.exception()) for task in tasks if task.done()]
    exceptions = [(task, err) for task, err in exceptions if err]
    for task, err in exceptions:
        log.error(f'close_loop reports exception:\n\t{task}\n\t{err}')

    # Handle shutdown gracefully by waiting for all tasks to be cancelled.
    log.debug(f'close_loop: gathering tasks: {tasks}')
    tasks = asyncio.gather(*tasks, loop=loop, return_exceptions=True)
    tasks.add_done_callback(lambda task: loop.stop())
    tasks.cancel()

    # Keep the event loop running until it is either destroyed or all
    # tasks have really terminated.
    log.debug('close_loop: wait for cancellation')
    while not tasks.done() and not loop.is_closed():
        loop.run_forever()

然后将2分钟之前的异常写入日志。见下文。

ERROR:mymodule.run:\close_loop reports exception:
    <Task finished coro=<Application._handle() done, defined at C:\Program Files\Python36\lib\site-packages\aiohttp\web_app.py:428> exception=ValueError('*******************',)>
    *******************

在应用程序运行时,我更希望在这些异常发生后进行记录和整理。我不喜欢这样的想法,即在应用程序存在之前会在内存中累积大量此类异常。

处理异步中徘徊的例外任务的最佳实践是什么?这种行为在任何地方都有定义吗?

0 个答案:

没有答案