--- cvsroot/AnyEvent-SNMP/SNMP.pm 2009/04/19 11:06:21 1.4 +++ cvsroot/AnyEvent-SNMP/SNMP.pm 2009/08/02 14:24:23 1.7 @@ -1,6 +1,6 @@ =head1 NAME -AnyEvent::SNMP - adaptor to integrate Net::SNMP into Anyevent. +AnyEvent::SNMP - adaptor to integrate Net::SNMP into AnyEvent. =head1 SYNOPSIS @@ -51,6 +51,8 @@ =item $AnyEvent::SNMP::MAX_OUTSTANDING (default: C<50>, dynamic) +=item AnyEvent::SNMP::set_max_outstanding $new_value + Use this package variable to restrict the number of outstanding SNMP requests at any point in time. @@ -63,8 +65,9 @@ case, this can lead to packet loss, when the receive queue overflows and the kernel can no longer accept new packets. -To avoid this, you can (and should) limit the number of outstanding requests -to a number low enough so that parsing time doesn't introduce noticable delays. +To avoid this, you can (and should) limit the number of outstanding +requests to a number low enough so that parsing time doesn't introduce +noticable delays. Unfortunately, this number depends not only on processing speed and load of the machine running Net::SNMP, but also on the network latency and the @@ -73,10 +76,20 @@ AnyEvent::SNMP tries to dynamically adjust this number dynamically upwards and downwards. +Increasing C<$MAX_OUTSTANDING> will not automatically use the +C and make +C make use of the extra paralellity, call +C with the new value, e.g.: + + AnyEvent::SNMP::set_max_outstanding 500; + +Although due to the dynamic adjustment, this might have little lasting +effect. + Note that you can use L to speed up parsing of responses considerably. -=item $AnyEvent::SNMP::MIN_RECVQUEUE (default: C<4>) +=item $AnyEvent::SNMP::MIN_RECVQUEUE (default: C<8>) =item $AnyEvent::SNMP::MAX_RECVQUEUE (default: C<64>) @@ -145,10 +158,10 @@ AnyEvent::post_detect { $timer = AnyEvent->can ("timer") }; our $BUSY; -our %TRANSPORT; # address => [count, watcher] +our @TRANSPORT; # fileno => [count, watcher] our @QUEUE; our $MAX_OUTSTANDING = 50; -our $MIN_RECVQUEUE = 4; +our $MIN_RECVQUEUE = 8; our $MAX_RECVQUEUE = 64; sub kick_job; @@ -194,10 +207,11 @@ # Schedule the timeout handler if the message expects a response. if ($pdu->expect_response) { my $transport = $msg->transport; + my $fileno = $transport->fileno; # register the transport - unless ($TRANSPORT{$transport+0}[0]++) { - $TRANSPORT{$transport+0}[1] = AnyEvent->io (fh => $transport->socket, poll => 'r', cb => sub { + unless ($TRANSPORT[$fileno][0]++) { + $TRANSPORT[$fileno][1] = AnyEvent->io (fh => $transport->socket, poll => 'r', cb => sub { for my $count (1..$MAX_RECVQUEUE) { # handle up to this many requests in one go # Create a new Message object to receive the response my ($msg, $error) = Net::SNMP::Message->new (-transport => $transport); @@ -217,8 +231,8 @@ } } else { # for some reason, connected-oriented transports seem to need this - delete $TRANSPORT{$transport+0} - unless --$TRANSPORT{$transport+0}[0]; + delete $TRANSPORT[$fileno] + unless --$TRANSPORT[$fileno][0]; } $msg->error; @@ -251,8 +265,8 @@ --$BUSY; kick_job; - unless (--$TRANSPORT{$transport+0}[0]) { - delete $TRANSPORT{$transport+0}; + unless (--$TRANSPORT[$fileno][0]) { + delete $TRANSPORT[$fileno]; return; } } @@ -261,7 +275,7 @@ # when we end up here, we successfully handled $MAX_RECVQUEUE # replies in one iteration, so assume we are overloaded # and reduce the amount of parallelity. - $MAX_OUTSTANDING = (int $MAX_OUTSTANDING * 0.9) || 1; + $MAX_OUTSTANDING = (int $MAX_OUTSTANDING * 0.95) || 1; }); } @@ -270,8 +284,8 @@ my $rtimeout_w = $msg->timeout_id; if ($$rtimeout_w) { undef $$rtimeout_w; - delete $TRANSPORT{$transport+0} - unless --$TRANSPORT{$transport+0}[0]; + delete $TRANSPORT[$fileno] + unless --$TRANSPORT[$fileno][0]; } if ($retries--) { @@ -301,6 +315,7 @@ _send_pdu $pdu, $pdu->retries; } } + sub send_pdu($$$) { my (undef, $pdu, $delay) = @_; @@ -331,6 +346,11 @@ AnyEvent->one_event; } +sub set_max_outstanding($) { + $MAX_OUTSTANDING = $_[0]; + kick_job; +} + =head1 SEE ALSO L, L, L, L.