SNMP-Multi
view release on metacpan or search on metacpan
my $rsessions = $multi->{_sessions};
# Any extra arguments for SNMP::Session?
#
my @SNMPargs = @{$multi->{_SNMPArgs}};
# Iterate through the round-robin list, popping host/index pairs off of
# the front of @rrhosts, and pushing the "next" pair on the end if more
# requests remain.
#
RR: while (@{$multi->{_reqlist}}) {
# Pull the next host/index pair off of the front of @rrhosts.
#
my $host = shift @{$multi->{_reqlist}};
my $index = shift @{$multi->{_reqlist}};
my $rhost = $multi->{_hosts}{$host};
# Skip this host/index if a new session to that host is needed,
# but there are no available sessions.
#
my $rsess = $rsessions->{$host};
if (!defined($rsess) && !$availsess) {
print "No SNMP sessions available for $host (all "
. "$multi->{MaxSessions} sessions in use)\n" if $DEBUGGING;
# Push the request on the tail of the retry request list.
push @retry, ($host, $index);
next RR;
}
# There is either a current session for this host, or a new one can
# be created. Get handles for the metadata for this host.
#
my $rreqs = $rhost->{requests};
my $nreqs = scalar @$rreqs;
croak "Request $host:$index outside range [0..$nreqs]"
unless ($index < $nreqs);
# Get a reference to the request, and its additional arguments.
#
my $request = $rreqs->[$index];
croak "Request is undef!" unless defined $request;
my $rargs = $rhost->{sendargs}->[$index];
# Create a new session for this request if one does not already exist.
unless (defined $rsess) {
$! = 0; # Reset system errno before calling new() (see below)
$rsess = SNMP::Session->new( @SNMPargs,
DestHost => $host,
Community => $rhost->{community},
Version => $rhost->{snmpversion},
Timeout => $multi->{Timeout} * 1e6,
Retries => $multi->{Retries},
TimeStamp => $multi->{TimeStamp},
#UseNumeric => $multi->{UseNumeric},
# UseNumeric BOMBS PERL CORE !!!
UseNumeric => 0,
);
# Give up on this particular request for now. At some point in
# the future, we should probably flag the session as failed, and
# provide an option to avoid retrying any further requests on the
# host.
#
# This is a little tricky -- SNMP::Session::new() doesn't set any
# sort of error flag. We can, however, tell if it was a hostname
# lookup failure by examining $! (errno). It will be 0 if the
# problem occurred before the call into the XS code, otherwise
# a system-level error occured which we can trap based on $!.
#
unless (defined $rsess) {
my $err;
unless ($!) {
# Couldn't look up the host, so set the error code
# especially for this.
$err = "Couldn't resolve hostname";
# We are discarding this request.
#
$rhost->{remain} --;
$multi->{_remain} --;
} else {
# Some system-level error occurred. Handle a few simple
# resource problems by (hopefully) waiting for things to
# subside, and retry later.
#
# Copy error string, and force numeric errno
$err = "" . $!;
my $errno = $! + 0;
if (($errno == EINTR) || # Interrupted system call
($errno == EAGAIN) || # Resource temp. unavailable
($errno == ENOMEM) || # No memory (temporary)
($errno == ENFILE) || # Out of file descriptors
($errno == EMFILE)) # Too many open fd's
{
# Push the request onto the retry request list.
push @retry, ($host, $index);
# Prevent further attempts to get a new session
# until the blockage clears, but only if there's
# a chance a current connection will finish and
# free up resources.
$availsess = 0 if $multi->{_nsessions};
# Note that we'll retry later.
$err .= " (will retry)";
} else {
# We are discarding this request.
#
$rhost->{remain} --;
$multi->{_remain} --;
}
}
( run in 2.036 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )