Skip to content
Draft

test #23261

Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions snmp/datadog_checks/snmp/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ def discover_instances(config, interval, check_ref):
_prev_loop = asyncio.get_event_loop()
except RuntimeError:
_prev_loop = None
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

try:
while True:
Expand All @@ -44,23 +42,28 @@ def discover_instances(config, interval, check_ref):
if check is None or not check._running:
return

host_config = check._build_autodiscovery_config(config.instance, host)
# Create a fresh event loop per host so that close_dispatcher() cleanup
# from one host cannot contaminate the next host's SNMP session.
# The loop must be set before _build_autodiscovery_config because
# pysnmp 7.x's SnmpEngine captures the event loop at construction time.
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

host_config = check._build_autodiscovery_config(config.instance, host)
try:
sys_object_oid = check.fetch_sysobject_oid(host_config)
except Exception as e:
check.log.debug("Error scanning host %s: %s", host, e)
del check
continue
finally:
# Close the host's transport dispatcher to release its UDP socket FD, then
# drain any leftover handle_timeout tasks so they don't stop the next host's loop.
host_config._snmp_engine.transport_dispatcher.close_dispatcher()
_pending = asyncio.all_tasks(loop)
for _t in _pending:
_t.cancel()
if _pending:
loop.run_until_complete(asyncio.gather(*_pending, return_exceptions=True))
loop.close()

try:
profile = check._profile_for_sysobject_oid(sys_object_oid)
Expand Down Expand Up @@ -89,11 +92,4 @@ def discover_instances(config, interval, check_ref):
if interval - time_elapsed > 0:
time.sleep(interval - time_elapsed)
finally:
# Cancel pending pysnmp tasks and close the loop to release file descriptors.
pending = asyncio.all_tasks(loop)
for task in pending:
task.cancel()
if pending:
loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
loop.close()
asyncio.set_event_loop(_prev_loop)
Loading