Qiang has asked for the wisdom of the Perl Monks concerning the following question:

hi, i have piece of code utilizing Net::SNMP to query printers. sometimes it takes real long time to finish the query.I have used the -timeout and it doesn't appear do anything. now i am using eval and alarm but run into a problem.
sub fun1 { foreach (printers ){ my ($session, $error) = Net::SNMP->session( -hostname => $ip, -community => chomp($cmnt), -port => 161, -timeout => 5, ); my $result = $session->get_request( -varbindlist => [$OID] ); eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm 5; $result = $session->get_request( -varbindlist => [$oid] ); alarm 0; }; $row .= lc($result->{$oid})."-"; } }
in the foreachloop, only the first loop times out within the eval block. the rest of loops takes less than 5 seconds to finish. however, after the first loop, $result->{$oid} is always empty. which isn't if i take out of the eval block. any idea ?

Replies are listed 'Best First'.
Re: eval alarm on mod_perl
by Roger (Parson) on Feb 18, 2004 at 07:15 UTC
    You code just added to the confusion. To start with, let's clarify your code a bit:

    - You have two get_request calls, one outside eval and one inside eval, is that how it looks in your script?

    - You are calling with different values of oid in the get_request, one is lowercase $oid, one is upper case $OID.
      sorry about the confusion. here is the code in full.
      sub create_pr_table { my $get_pr_names = shift; my $row; # printer status my $OID = ".1.3.6.1.4.1.11.2.4.3.1.2.0"; # LCD messages my @OIDs = (".1.3.6.1.2.1.43.16.5.1.2.1.1", # ".1.3.6.1.2.1.43.16.5.1.2.1.2", # ".1.3.6.1.2.1.43.16.5.1.2.1.3", ); my $pr_section_name; # create the printer snmp info in html tag foreach $pr_section_name (values %{$config}) { my $pr_name = $pr_section_name->{pr_name}; next unless $pr_name; $pr_names{$pr_name}=""; # called from show_lpq_info and only need printer names info. next if $get_pr_names == 1; my $cmnt = $pr_section_name->{cmnt}; my $ip = $pr_section_name->{ip}; $row .= "<tr>"; $row .= "<td nowrap><a href=index.pl?printer=$pr_name><font fa +ce=\"arial\" size=2>$pr_name</font></a></td>"; my ($session, $error) = Net::SNMP->session( -hostname => $ip, -community => chomp($cmnt), -port => 161, -timeout => 5, ); if (!defined($session)) { print STDERR $error; next; } # printer status row my $result = $session->get_request( -varbindlist => [$OID] ); $row .= "<td nowrap><font face=\"arial\" size=2>".lc($result-> +{$OID})."&nbsp;</font></td>"; # LCD messages $row .="<td nowrap><font face=\"arial\" size=2>"; foreach my $oid (@OIDs) { #eval { #local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required #alarm 5; $result = $session->get_request( -varbindlist => [$oid] ); #alarm 0; #}; $row .= lc($result->{$oid})."&nbsp;"; # last if $result->{$oid} =~ m#powersave on#i; } $row .="</font></td>"; # get this printer's queue my $queues = get_lpq_info($pr_name,1); $row .= "<td nowrap><center><font face=\"arial\" size=2>$queue +s</font></center></td>"; $row .= "</tr>"; } return $row; }
      the eval part is commented out now. within every loop of the first foreach, it queries a printer for status etc via SNMP.
Re: eval alarm on mod_perl
by simonm (Vicar) on Feb 18, 2004 at 19:37 UTC
    It may be that alarming out of the middle of a Net::SNMP operation causes that session to be left in an inconsistent state.

    You could test this by having the $SIG{ALRM} set a flag or clear out the $session, and then starting a new session before the next request.