summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2011-11-27 08:10:43 +0000
committerelie <elie>2011-11-27 08:10:43 +0000
commit58387b60f13e043f14770e32a3d9c56bb5e1ece8 (patch)
treed2540165e290f34c87f28df8ae2cae2c9bae8efb
parent1044efb39e0968eeae2576e8d08ab770298938df (diff)
downloadpysnmp-58387b60f13e043f14770e32a3d9c56bb5e1ece8.tar.gz
transport dispatcher now provides its own time expressed in
fractions of second. SNMP engine uses this notion of time for handling requests timeout to make packet flow time bound
-rw-r--r--pysnmp/carrier/base.py20
-rw-r--r--pysnmp/carrier/twisted/dispatch.py8
-rw-r--r--pysnmp/entity/rfc3413/cmdgen.py8
-rw-r--r--pysnmp/entity/rfc3413/ntforg.py16
-rw-r--r--pysnmp/proto/rfc3412.py11
5 files changed, 47 insertions, 16 deletions
diff --git a/pysnmp/carrier/base.py b/pysnmp/carrier/base.py
index 5701043..cc0fdd7 100644
--- a/pysnmp/carrier/base.py
+++ b/pysnmp/carrier/base.py
@@ -25,7 +25,10 @@ class AbstractTransportDispatcher:
self.__jobs = {}
self.__recvCbFun = None
self.__timerCallables = []
-
+ self.__ticks = 0
+ self.__timerResolution = 0.5
+ self.__lastTime = 0
+
def _cbFun(self, incomingTransport, transportAddress, incomingMessage):
for name, transport in self.__transports.items():
if transport is incomingTransport:
@@ -96,7 +99,22 @@ class AbstractTransportDispatcher:
'No suitable transport domain for %s' % (transportDomain,)
)
+ def getTimerResolution(self):
+ return self.__timerResolution
+ def setTimerResolution(self, timerResolution):
+ if timerResolution < 0.01 or timerResolution > 10:
+ raise error.CarrierError('Impossible timer resolution')
+ self.__timerResolution = timerResolution
+
+ def getTimerTicks(self): return self.__ticks
+
def handleTimerTick(self, timeNow):
+ if self.__lastTime + self.__timerResolution > timeNow:
+ return
+
+ self.__ticks += 1
+ self.__lastTime = timeNow
+
for timerCallable in self.__timerCallables:
timerCallable(timeNow)
diff --git a/pysnmp/carrier/twisted/dispatch.py b/pysnmp/carrier/twisted/dispatch.py
index 89e1629..7304e95 100644
--- a/pysnmp/carrier/twisted/dispatch.py
+++ b/pysnmp/carrier/twisted/dispatch.py
@@ -19,9 +19,9 @@ class TwistedDispatcher(AbstractTransportDispatcher):
AbstractTransportDispatcher.__init__(self)
self.__transportCount = 0
if 'timeout' in kwargs:
- self.timeout = kwargs['timeout']
+ self.setTimerResolution(kwargs['timeout'])
else:
- self.timeout = 1.0
+ self.setTimerResolution(1.0)
self.loopingcall = task.LoopingCall(self.handleTimeout)
def handleTimeout(self):
@@ -37,8 +37,8 @@ class TwistedDispatcher(AbstractTransportDispatcher):
# jobstarted/jobfinished might be okay as-is
def registerTransport(self, tDomain, transport):
- if not self.loopingcall.running and self.timeout > 0:
- self.loopingcall.start(self.timeout, now = False)
+ if not self.loopingcall.running and self.getTimerResolution() > 0:
+ self.loopingcall.start(self.getTimerResolution(), now = False)
AbstractTransportDispatcher.registerTransport(
self, tDomain, transport
)
diff --git a/pysnmp/entity/rfc3413/cmdgen.py b/pysnmp/entity/rfc3413/cmdgen.py
index d9666d1..478e2cc 100644
--- a/pysnmp/entity/rfc3413/cmdgen.py
+++ b/pysnmp/entity/rfc3413/cmdgen.py
@@ -180,6 +180,10 @@ class CommandGeneratorBase:
cbInfo
):
(processResponsePdu, cbCtx) = cbInfo
+
+ # Convert timeout in seconds into timeout in timer ticks
+ timeoutInTicks = float(timeout)/100/snmpEngine.transportDispatcher.getTimerResolution()
+
# 3.1
sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu(
snmpEngine,
@@ -193,8 +197,8 @@ class CommandGeneratorBase:
contextName,
pduVersion,
reqPDU,
- 1, # expectResponse
- float(timeout)/100 + time.time(), # timeout
+ 1, # expectResponse
+ timeoutInTicks,
processResponsePdu,
cbCtx
)
diff --git a/pysnmp/entity/rfc3413/ntforg.py b/pysnmp/entity/rfc3413/ntforg.py
index fb5599f..ec18e96 100644
--- a/pysnmp/entity/rfc3413/ntforg.py
+++ b/pysnmp/entity/rfc3413/ntforg.py
@@ -61,7 +61,10 @@ class NotificationOriginator:
cbFun,
cbCtx)
return
-
+
+ # Convert timeout in seconds into timeout in timer ticks
+ timeoutInTicks = float(origTimeout)/100/snmpEngine.transportDispatcher.getTimerResolution()
+
# 3.3.6a
sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu(
snmpEngine,
@@ -75,8 +78,8 @@ class NotificationOriginator:
origContextName,
origPduVersion,
origPdu,
- 1, # expectResponse
- float(origTimeout)/100 + time.time(), # timeout
+ 1, # expectResponse
+ timeoutInTicks,
self.processResponsePdu,
(cbFun, cbCtx)
)
@@ -235,6 +238,9 @@ class NotificationOriginator:
None
)
else:
+ # Convert timeout in seconds into timeout in timer ticks
+ timeoutInTicks = float(timeout)/100/snmpEngine.transportDispatcher.getTimerResolution()
+
# 3.3.6a
sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu(
snmpEngine,
@@ -248,8 +254,8 @@ class NotificationOriginator:
contextName,
pduVersion,
pdu,
- 1, # expectResponse
- float(timeout)/100 + time.time(), # timeout
+ 1, # expectResponse
+ timeoutInTicks,
self.processResponsePdu,
(cbFun, cbCtx)
)
diff --git a/pysnmp/proto/rfc3412.py b/pysnmp/proto/rfc3412.py
index b940847..11c7233 100644
--- a/pysnmp/proto/rfc3412.py
+++ b/pysnmp/proto/rfc3412.py
@@ -1,5 +1,5 @@
"""SNMP v3 Message Processing and Dispatching (RFC3412)"""
-import time, sys
+import sys
from pyasn1.compat.octets import null
from pysnmp.smi import builder, instrum
from pysnmp.proto import errind, error, cache
@@ -104,7 +104,7 @@ class MsgAndPduDispatcher:
pduVersion,
PDU,
expectResponse,
- timeout=0, # response items
+ timeout=0, # timeout expressed in dispatcher ticks
cbFun=None,
cbCtx=None
):
@@ -127,10 +127,11 @@ class MsgAndPduDispatcher:
sendPduHandle,
messageProcessingModel=messageProcessingModel,
sendPduHandle=sendPduHandle,
- timeout=timeout,
+ timeout=timeout+snmpEngine.transportDispatcher.getTimerTicks(),
cbFun=cbFun,
cbCtx=cbCtx
)
+ debug.logger & debug.flagDsp and debug.logger('sendPdu: current time in ticks %d' % (snmpEngine.transportDispatcher.getTimerTicks(),))
debug.logger & debug.flagDsp and debug.logger('sendPdu: new sendPduHandle %s, timeout %s, cbFun %s' % (sendPduHandle, timeout, cbFun))
@@ -456,8 +457,10 @@ class MsgAndPduDispatcher:
def __expireRequest(self, cacheKey, cachedParams, snmpEngine,
statusInformation=None):
+ timeNow = snmpEngine.transportDispatcher.getTimerTicks()
timeoutAt = cachedParams['timeout']
- if statusInformation is None and time.time() < timeoutAt:
+
+ if statusInformation is None and timeNow < timeoutAt:
return
processResponsePdu = cachedParams['cbFun']