#!/usr/bin/perl package SNMP::Query::AsynchMulti; use strict; use warnings; use Carp; use SNMP; sub new { my $class = shift; my $self = bless {}, $class; $self->{query_stack} = []; $self->{results} = []; $self->{max_in_flight} = 10; $self->{current_in_flight} = 0; $self->{total_query_count} = 0; return $self; } sub add { my $self = shift; my $params = shift; my $query_stack = $self->{query_stack}; my $sess = $params->{Session} || croak "Session parameter must be specified"; my $varbinds = $params->{VarBinds} || croak "VarBinds parameter must be specified"; my $query_type = $params->{QueryType} || 'getbulk'; if ($query_type eq 'getbulk') { my $non_repeaters = $params->{NonRepeaters} || 0; my $max_repeaters = $params->{MaxRepeaters} || 10; my $query = $self->_make_getbulk_query($sess, $varbinds, $non_repeaters, $max_repeaters); push @$query_stack, $query; } else { croak "Attempt to add using unknown query type: $query_type\n"; } return 1; } sub _make_getbulk_query { my $self = shift; my ($sess,$varbinds,$non_repeaters,$max_repeaters) = @_; return sub { my $callback = sub { my $bulkwalk_results = shift; push @{$self->{results}}, "Query Complete", $bulkwalk_results; $self->{current_in_flight}--; warn "Finished Query\n"; if (scalar @{$self->{query_stack}}) { my $next_query = pop @{$self->{query_stack}}; return $next_query->(); } return SNMP::finish() if $self->{current_in_flight} <= 0; }; $self->{current_in_flight}++; $self->{total_query_count}++; warn "Started query $self->{total_query_count}\n"; return $sess->bulkwalk($non_repeaters, $max_repeaters, $varbinds, [$callback]); }; } sub shuffle {} # TODO implement shuffle with List::Util or something sub execute { my $self = shift; my $params = shift; @{$self->{results}} = (); $self->{current_in_flight} = 0; my $max_in_flight = $params->{InFlight} || $self->{max_in_flight}; my $query_stack_ref = $self->{query_stack}; my @query_stack_copy = @{$self->{query_stack}}; while (scalar @$query_stack_ref) { my $query = pop @$query_stack_ref; $query->(); last if $self->{current_in_flight} >= $max_in_flight; } SNMP::MainLoop(); #use Data::Dumper; warn Dumper $self->{query_stack}, \@query_stack_copy; exit; $self->{query_stack} = \@query_stack_copy; return \@{$self->{results}}; } 1; __END__