asyncio之调试asyncio

调试asyncio

asyncio中内置了几个有用的调试功能。
首先,事件循环在运行时使用日志来发送状态消息。如果在应用程序中启用日志记录,则其中的一些功能可用。其他的可以通过告诉循环发出更多的调试消息来打开。调用set_debug()传递布尔值,指示是否应该启用调试。
因为构建在asyncio上的应用程序对贪婪的协程不交出控制权高度敏感,因此有支持检测事件循环内置的慢回调。通过启用调试来打开它,并通过将循环的slow_callback_duration属性设置为发出警告的秒数来控制定义的“slow”。
最后,如果使用asyncio的应用程序退出而没有清除一些协程或其他资源,这可能意味着有一个逻辑错误阻止了一些应用程序代码的运行。启用ResourceWarning警告会导致在程序退出时报告这些情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import argparse
import asyncio
import logging
import sys
import time
import warnings
parser = argparse.ArgumentParser('debugging asyncio')
parser.add_argument(
'-v',
dest='verbose',
default=False,
action='store_true',
)
args = parser.parse_args()
logging.basicConfig(
level=logging.DEBUG,
format='%(levelname)7s: %(message)s',
stream=sys.stderr,
)
LOG = logging.getLogger('')
async def inner():
LOG.info('inner starting')
# Use a blocking sleep to simulate
# doing work inside the function.
time.sleep(0.1)
LOG.info('inner completed')
async def outer(loop):
LOG.info('outer starting')
await asyncio.ensure_future(loop.create_task(inner()))
LOG.info('outer completed')
event_loop = asyncio.get_event_loop()
if args.verbose:
LOG.info('enabling debugging')
# Enable debugging
event_loop.set_debug(True)
# Make the threshold for "slow" tasks very very small for
# illustration. The default is 0.1, or 100 milliseconds.
event_loop.slow_callback_duration = 0.001
# Report all mistakes managing asynchronous resources.
warnings.simplefilter('always', ResourceWarning)
LOG.info('entering event loop')
event_loop.run_until_complete(outer(event_loop))

在未启用调试的情况下运行时,此应用程序一切正常。

1
2
3
4
5
6
7
8
$ python3 asyncio_debug.py
DEBUG: Using selector: KqueueSelector
INFO: entering event loop
INFO: outer starting
INFO: inner starting
INFO: inner completed
INFO: outer completed

开启调试暴露了它的一些问题,事实上虽然inner()已经完成,但是这比设置的slow_callback_duration需要更多的时间,并且程序退出时事件循环未被正确关闭。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ python3 asyncio_debug.py -v
DEBUG: Using selector: KqueueSelector
INFO: enabling debugging
INFO: entering event loop
INFO: outer starting
INFO: inner starting
INFO: inner completed
WARNING: Executing <Task finished coro=<inner() done, defined at
asyncio_debug.py:34> result=None created at asyncio_debug.py:44>
took 0.102 seconds
INFO: outer completed
.../lib/python3.5/asyncio/base_events.py:429: ResourceWarning:
unclosed event loop <_UnixSelectorEventLoop running=False
closed=False debug=True>
DEBUG: Close <_UnixSelectorEventLoop running=False
closed=False debug=True>

本文翻译自《The Python3 Standard Library By Example》asyncio相关章节

文章目录
|