-
-
Couldn't load subscription status.
- Fork 39
Description
Expected behavior
I'm using pysnmp for an SNMP trap receiver. After starting the trap receiver, if I try to stop it with snmp_engine.transport_dispatcher.job_finished(1), snmp_engine.transport_dispatcher.close_dispatcher(), or snmp_engine.close_dispatcher(), it should stop.
My testing is loosely based on an example in the repo
Actual behavior
Instead, the dispatcher does not exit/close when I call the public methods. Instead, the only way I've found to close it is by using the private method snmp_engine.transport_dispatcher._AsyncioDispatcher__close_dispatcher()
I also tried closing it from within the trap handler when it was called, and that did not work either.
Detailed steps
I've attached a small script to reproduce it.
$ python3 pysnmp_bug.py
starting dispatcher
try job finished
still alive, try private method
dispatcher closed
Python package information
7.1.21
Operating system information
MacOS, though I've reproduced it on linux too
Python information
3.13.3
(Optional) Contents of your test script
"""minimal script to reproduce pysnmp dispatcher shutdown bug"""
import threading
import time
from pysnmp.carrier.asyncio.dgram import udp
from pysnmp.entity import config, engine
from pysnmp.entity.rfc3413 import ntfrcv
snmp_engine = engine.SnmpEngine()
config.add_transport(snmp_engine, udp.DOMAIN_NAME, udp.UdpTransport().open_server_mode(("0.0.0.0", 8162)))
def trap_callback(eng, state_ref, ctx_eng_id, ctx_name, var_binds, cb_ctx):
print("received trap: %s" % var_binds)
snmp_engine.transport_dispatcher.job_finished(1)
config.add_v1_system(snmp_engine, "test", "public")
ntfrcv.NotificationReceiver(snmp_engine, trap_callback)
def try_shutdown():
# wait for receiver to start
time.sleep(5)
# mark job finished to close dispatcher
print("try job finished")
snmp_engine.transport_dispatcher.job_finished(1)
time.sleep(5)
# these don't work either, and also block _AsyncioDispatcher__close_dispatcher() from working too?
# snmp_engine.transport_dispatcher.close_dispatcher()
# snmp_engine.close_dispatcher()
print("still alive, try private method")
snmp_engine.transport_dispatcher._AsyncioDispatcher__close_dispatcher()
threading.Thread(target=try_shutdown, daemon=True).start()
print("starting dispatcher")
snmp_engine.transport_dispatcher.job_started(1)
snmp_engine.open_dispatcher()
print("dispatcher closed")Relevant log output
$ python3 pysnmp_bug.py
starting dispatcher
try job finished
still alive, try private method
dispatcher closed