asyncio "任务已被破坏,但它正在等待处理!"在 pysnmp 示例程序中
Posted
技术标签:
【中文标题】asyncio "任务已被破坏,但它正在等待处理!"在 pysnmp 示例程序中【英文标题】:asyncio "Task was destroyed but it is pending!" in pysnmp sample program 【发布时间】:2017-01-08 23:57:25 【问题描述】:我正在测试 pysnmp asyncio 模块,一开始使用的是随文档一起提供的sample program。当我运行示例程序时,它给出了Task was destroyed but it is pending!
错误。我检查了类似的问题,但找不到我的(没有经验的)眼睛有什么问题。我在 Debian 8.5 上使用 Python 3.4.2 和随附的 asyncio 以及 pysnmp (4.3.2)
我使用的程序(与pysnmp文档中的示例程序相同)
import asyncio
from pysnmp.hlapi.asyncio import *
@asyncio.coroutine
def getone(snmpEngine, hostname):
errorIndication, errorStatus, errorIndex, varBinds = yield from getCmd(
snmpEngine,
CommunityData('public'),
UdpTransportTarget(hostname),
ContextData(),
ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))
)
if errorIndication:
print(errorIndication)
elif errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'
)
)
else:
for varBind in varBinds:
print(' = '.join([x.prettyPrint() for x in varBind]))
@asyncio.coroutine
def getall(snmpEngine, hostnames):
for hostname in hostnames:
yield from getone(snmpEngine, hostname)
snmpEngine = SnmpEngine()
loop = asyncio.get_event_loop()
loop.run_until_complete(getall(snmpEngine, [('demo.snmplabs.com', 1161),
('demo.snmplabs.com', 2161),
('demo.snmplabs.com', 3161)]))
错误是:
Executing wait_for= cb=[_raise_stop_error() at /usr/lib/python3.4/asyncio/base_event
s.py:101] created at /usr/lib/python3.4/asyncio/base_events.py:264> took 0.460 seconds
SNMPv2-MIB::sysDescr.0 = SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m
SNMPv2-MIB::sysDescr.0 = SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m
SNMPv2-MIB::sysDescr.0 = SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m
Task was destroyed but it is pending!
source_traceback: Object created at (most recent call last):
File "multiple-sequential-queries.py", line 58, in
('demo.snmplabs.com', 3161)]))
File "/usr/lib/python3.4/asyncio/base_events.py", line 271, in run_until_complete
self.run_forever()
File "/usr/lib/python3.4/asyncio/base_events.py", line 244, in run_forever
self._run_once()
File "/usr/lib/python3.4/asyncio/base_events.py", line 1075, in _run_once
handle._run()
File "/usr/lib/python3.4/asyncio/events.py", line 120, in _run
self._callback(*self._args)
File "/usr/lib/python3.4/asyncio/tasks.py", line 237, in _step
result = next(coro)
File "/usr/lib/python3.4/asyncio/coroutines.py", line 79, in __next__
return next(self.gen)
File "multiple-sequential-queries.py", line 50, in getall
yield from getone(snmpEngine, hostname)
File "/usr/lib/python3.4/asyncio/coroutines.py", line 79, in __next__
return next(self.gen)
File "multiple-sequential-queries.py", line 31, in getone
ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))
File "/usr/lib/python3.4/asyncio/coroutines.py", line 79, in __next__
return next(self.gen)
File "/usr/lib/python3.4/asyncio/coroutines.py", line 141, in coro
res = func(*args, **kw)
File "/usr/local/lib/python3.4/dist-packages/pysnmp/hlapi/asyncio/cmdgen.py", line 138, in getCmd
addrName, paramsName = lcd.configure(snmpEngine, authData, transportTarget)
File "/usr/local/lib/python3.4/dist-packages/pysnmp/hlapi/lcd.py", line 87, in configure
transport
File "/usr/local/lib/python3.4/dist-packages/pysnmp/entity/config.py", line 308, in addTransport
transport)
File "/usr/local/lib/python3.4/dist-packages/pysnmp/carrier/asyncio/dispatch.py", line 70, in registerTransport
self.loopingcall = asyncio.async(self.handle_timeout())
task: :4> wait_for= created at /usr/local/lib/python3.4/dist-packages/pysnmp/carrier/asyncio/dispatch.py:70>
非常感谢任何帮助解决这个问题!
谢谢。
【问题讨论】:
这看起来像 pysnmp 中与关闭时定期定时器功能取消有关的错误。这是有关此事的更多信息docs.python.org/3/library/…。在 github 上打开问题或发送 PR 可能是一种方法。 ;) 谢谢!让我打开一个问题。 【参考方案1】:pysnmp 中有一个内部计时器函数,用于处理缓存、重试等。使用异步传输,该计时器由 asyncio Future
驱动。您观察到的消息警告您,在主循环关闭之前,Future 对象仍处于挂起状态。
要解决此问题,您需要在完成所有 SNMP I/O 后取消挂起的计时器任务。一种 [hackerish] 方法是将以下 sn-p 附加到您提到的示例脚本中:
...
snmpEngine = SnmpEngine()
loop = asyncio.get_event_loop()
loop.run_until_complete(getall(snmpEngine, [('demo.snmplabs.com', 1161),
('demo.snmplabs.com', 2161),
('demo.snmplabs.com', 3161)]))
# run a coroutine to cancel pending timer task
from pysnmp.hlapi.asyncore.cmdgen import lcd
@asyncio.coroutine
def unconfigure(snmpEngine, authData=None):
lcd.unconfigure(snmpEngine, authData)
loop.run_until_complete(unconfigure(snmpEngine))
我正在努力将类似的协程添加到 pysnmp 中,以便您可以开箱即用地运行它。
【讨论】:
以上是关于asyncio "任务已被破坏,但它正在等待处理!"在 pysnmp 示例程序中的主要内容,如果未能解决你的问题,请参考以下文章
Python3 asyncio“任务已被破坏,但处于待处理状态”,具有某些特定条件