how can I clear the pySNMP timout?
Question
I would like to check tree system's status, I'm using the following code, but I have problem with the timeout, for example when one of the system is down than in the next system I'm getting a time out as well.
try:
snmp = pySNMPCom( ip="192.168.0.1", 23434, 30 )
"""It's hangig 30 seconds that is the timeout"""
data = snmp.emite_command( command )
snmp.destroye()
except:
"""Smtp timeout"""
snmp.destroye()
try:
snmp = pySNMPCom( ip="192.168.0.2", 23434, 30 )
"""It's going to the exception immediately, it suppose to hung 30 seconds..."""
data = snmp.emite_command( command )
snmp.destroye()
except:
"""Smtp timeout"""
snmp.destroye()
The class:
# -*- coding: utf-8 -*-
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto import api
from time import time
class pySNMPCom():
def __init__( self, ip, port, timeout ):
self.__host = ip
self.__port = port
self.__timeout = timeout
def set_cmd( self, cmd ):
self.cmd = cmd
def __set_message( self ):
self.__pMod = api.protoModules[api.protoVersion1]
self.__reqPDU = self.__pMod.GetRequestPDU()
self.__pMod.apiPDU.setDefaults( self.__reqPDU )
self.__pMod.apiPDU.setVarBinds(
self.__reqPDU, ( ( self.cmd, self.__pMod.Null( '' ) ),
)
)
# Build message
self.__reqMsg = self.__pMod.Message()
self.__pMod.apiMessage.setDefaults( self.__reqMsg )
self.__pMod.apiMessage.setCommunity( self.__reqMsg, 'public' )
self.__pMod.apiMessage.setPDU( self.__reqMsg, self.__reqPDU )
def __cbTimerFun( self, timeNow, startedAt = time() ):
if timeNow - startedAt > self.__timeout:
raise "Request timed out"
def __cbRecvFun( self, transportDispatcher, transportDomain, transportAddress, wholeMsg, reqPDU = '' ):
if not reqPDU:
reqPDU = self.__reqPDU
self.ret = ''
while wholeMsg:
rspMsg, wholeMsg = decoder.decode( wholeMsg, asn1Spec = self.__pMod.Message() )
rspPDU = self.__pMod.apiMessage.getPDU( rspMsg )
# Match response to request
if self.__pMod.apiPDU.getRequestID( reqPDU ) == self.__pMod.apiPDU.getRequestID( rspPDU ):
# Check for SNMP errors reported
errorStatus = self.__pMod.apiPDU.getErrorStatus( rspPDU )
if errorStatus:
print errorStatus.prettyPrint()
else:
for oid, val in self.__pMod.apiPDU.getVarBinds( rspPDU ):
self.ret = val
transportDispatcher.jobFinished( 1 )
def emite_command( self, cmd = '' ):
if not cmd:
cmd = self.cmd
self.set_cmd( cmd )
self.__set_message()
transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerTransport(
udp.domainName, udp.UdpSocketTransport().openClientMode()
)
transportDispatcher.registerRecvCbFun( self.__cbRecvFun )
transportDispatcher.registerTimerCbFun( self.__cbTimerFun )
transportDispatcher.sendMessage(
encoder.encode( self.__reqMsg ), udp.domainName, ( self.__host, self.__port )
)
transportDispatcher.jobStarted( 1 )
transportDispatcher.runDispatcher()
transportDispatcher.closeDispatcher()
return self.ret
def destroye( self ):
del self
Solution
You initialize the startedAt variable as a defaulted method parameter. That happens only once in a module runtime and never repeats on class re-instantiation. So all your queries timings are measured against the initial staredAt value. Therefore all queries occurring past startedAt + 30 will timeout right away.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow