Skip to content

Commit

Permalink
Keep global registry of SNMP session objects
Browse files Browse the repository at this point in the history
Before this, every Task instance would create its own SNMP session
instance.  This might not mean much under PySNMP, but is wasteful
using netsnmp-cffi, as each open session takes up a socket resource.
Having multiple simultaneous sessions/sockets per poll device makes
no sense, so `get_snmp_session()` utilizes a `WeakValueDictionary`
to keep track of the existing session for each device and returns
and existing session if there is one.
  • Loading branch information
lunkwill42 committed Jan 23, 2025
1 parent 7ebf942 commit 1af8f28
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
20 changes: 20 additions & 0 deletions src/zino/snmp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
"""Zino SNMP back-ends"""

from weakref import WeakValueDictionary

from zino.config.models import PollDevice

# There is only one at the moment:
# from .pysnmp_backend import * # noqa
from .netsnmpy_backend import * # noqa
from .netsnmpy_backend import SNMP

_snmp_sessions = WeakValueDictionary()


def get_snmp_session(device: PollDevice) -> SNMP:
"""Factory function for creating an SNMP session.
This keeps a registry of existing/re-usable SNMP sessions so we avoid duplicate instances and over-use of sockets
"""
# We generate a session key based on every attribute that affects how the SNMP session is set up:
key = (device.address, device.community, device.hcounters)
session = _snmp_sessions.get(key)
if not session:
session = _snmp_sessions[key] = SNMP(device)
return session
4 changes: 2 additions & 2 deletions src/zino/tasks/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import TYPE_CHECKING

from zino.config.models import PollDevice
from zino.snmp import SNMP
from zino.snmp import get_snmp_session

if TYPE_CHECKING:
from zino.state import ZinoState
Expand All @@ -16,7 +16,7 @@ class Task(ABC):
def __init__(self, device: PollDevice, state: ZinoState):
self.device = device
self.state = state
self.snmp = SNMP(device=device)
self.snmp = get_snmp_session(device=device)

@abstractmethod
async def run(self):
Expand Down

0 comments on commit 1af8f28

Please sign in to comment.