Skip Menu |

This queue is for tickets about the Net-SNMP CPAN distribution.

Report information
The Basics
Id: 58746
Status: rejected
Worked: 10 min
Priority: 0/
Queue: Net-SNMP

People
Owner: dtown [...] cpan.org
Requestors: BitCard [...] ResonatorSoft.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in:
  • 5.2.0
  • v6.0.0
Fixed in: (no value)



Subject: Add documentation for snmp_dispatch_once
I noticed that your POD didn't have documentation for the snmp_dispatch_once sub, nor any exports for this sub. I've been using this sub for years to process a bunch of the same OIDs for different hosts, using the non-blocking methods. I have wrapper subs that simplify the process, which boils down to this type of set up: Preload: Open X number of sessions as non-blocking (X = something like 50) Feed the list of OIDs for each of those sessions, pointing to a snmp_process_into_cache sub Process into cache: Put the OID result into a cache If all of the OIDs are done for that host, mark SNMP_PRELOAD_STATUS Loaded loop: Starts the preloading Goes into a loop: Hits snmp_dispatch_once if SNMP_PRELOAD_STATUS is done for a host: Run through the analyze data sub (which looks through the cache) Close the host Preload one more new host (if there are any more) Keep going until all of the hosts have been preloaded and analyzed The result is a really fast polling engine that burns through several thousand OIDs a minute. The engine can be further optimized through forking and multi-core processors. I can share these subs to you as an example, though they should probably be simplified for documentation use. Another option would be to convert them to be inserted into the Net::SNMP codebase.
From: BitCard [...] ResonatorSoft.org
I realized that some of that could still be achieved with snmp_dispatcher, so I wrote another example to be put into the POD documentation. This would probably fulfill the bug, rather than talking about snmp_dispatch_once. Here's the POD code. You will likely need to look at it from the text/plain download from RT to get the right space formatting. ----------------------- =head2 5. Non-blocking SNMPv1 get-request on multiple hosts and multiple OIDs (with poll buffering) This example polls many different hosts using multiple OIDs. Unlike the previous example, this one only polls a set number of hosts at a time. The results are cached until the host has given all of the information. Then the results are printed, the host's cache is removed, and another host is loaded. This will keep exactly $MAX_HOST hosts (currently set to 5) polling at all times. This set up is good for a large amount of hosts polling the same data. With the right machine, retry/timeout settings, and max number of hosts, this set up could poll hundreds of hosts a minute. Forking to multiple processes on a multi-core system would produce even faster polling. #! /usr/local/bin/perl use strict; use warnings; use Net::SNMP; # Some constants/globals my $MAX_HOSTS = 5; my %LOADED; my %CACHE; # Hash of OIDs my %OID = ( 'sysUpTime' => '1.3.6.1.2.1.1.3.0', 'sysContact' => '1.3.6.1.2.1.1.4.0', 'sysLocation' => '1.3.6.1.2.1.1.6.0', ); # Hash of hosts and location data. my %host_data = ( '10.1.1.1' => 'Building 1, First Floor', '10.1.1.2' => 'Building 1, Second Floor', '10.2.1.1' => 'Building 2, First Floor', '10.2.1.2' => 'Building 2, Second Floor', '10.3.1.1' => 'Building 3, First Floor', '10.3.1.2' => 'Building 3, Second Floor', '10.4.1.1' => 'Building 4, First Floor', '10.4.1.2' => 'Building 4, Second Floor', '10.5.1.1' => 'Building 5, First Floor', '10.5.1.2' => 'Building 5, Second Floor', 'localhost' => 'Right here!', ); my @HOST_LIST = sort keys %host_data; # Load the hosts up to MAX_HOSTS for my $i (1 .. $MAX_HOSTS) { my $host = shift @HOST_LIST; &load_host($host); } # Now initiate the SNMP message exchange. snmp_dispatcher(); exit 0; # Opens the session and send the get_requests for the specific host sub load_host { my ($host) = @_; my ($session, $error) = Net::SNMP->session( -hostname => $host, -community => 'private', -nonblocking => 1, ); if (!defined $session) { printf "ERROR: Failed to create session for host '%s': %s.\n", $host, $error; next; } for my $oid_name (sort keys %OID) { my $result = $session->get_request( -varbindlist => [$OID{$oid_name}], -callback => [ \&get_callback, $host, $oid_name ], ); if (!defined $result) { printf "ERROR: Failed to queue get request for host '%s': %s.\n", $session->hostname(), $session->error(); } $LOADED{$host}->{$oid_name} = 1; } return; } # Process each OID, cache them, and then run the print_host function when # all of the OIDs are collected for that host sub get_callback { my ($session, $host, $oid_name) = @_; delete $LOADED{$host}->{$oid_name}; my $result = $session->var_bind_list; if (!defined $result) { printf "ERROR: Get request failed for host '%s': %s.\n", $session->hostname(), $session->error(); return; } my @values = values %{$result}; $CACHE{$host}->{$oid_name} = $values[0]; # If we are finished with all of the OIDs, print the details, remove # the cache, and load another host unless (keys %{$LOADED{$host}}) { &print_host($host); delete $CACHE{$host}; if (@HOST_LIST) { my $new_host = shift @HOST_LIST; &load_host($new_host); } } return; } sub print_host { my ($host) = @_; print $host_data{$host}.":\n"; for my $oid_name (sort keys %OID) { print "\t$oid_name: ".$CACHE{$host}->{$oid_name}."\n"; } return; }
The snmp_dispatch_once() method was provided as a general side effect of how event loops are written. It is present and exportable upon request, but left undocumented (a.k.a. unsupported) because there are a lot of complications when trying to generically deal with multiple event loops. The AnyEvent::SNMP module provides a mechanism to tie the Net::SNMP event loop into other event driven implementations. This module should be used where appropriate. I will consider you code suggestion/documentation for the next release. I have however tried to keep the documentation examples minimalistic to just show the usage of the API and not get too deep into application implementations. In your example you could also request all of the OIDs in a single get-request.