问题
So I've researched to the ends of the internet (at least I think so) about this issue. I'm trying to set an alarm
timeout of 60 seconds for a get()
but it does not get caught and will run past 60 seconds, also any time the default timeout (180 sec) is reached for the www::mechanized::timed constructor, I get the error below:
Use of uninitialized value in addition (+) at /usr/lib/perl5/site_perl/5.10.0/WWW/Mechanize/Timed.pm line 52.
code:
use WWW::Mechanize::Timed;
use HTTP::Cookies;
use Try::Tiny;
my $ua = WWW::Mechanize::Timed->new(
autocheck => 0#turning off autocheck becuase any get errors will be fatal need to check ourselves
);
my $cookies = HTTP::Cookies->new(
autosave => 1
);
$ua->cookie_jar($cookies);
$ua->agent_alias("Windows IE 6");
try{
local $SIG{ALRM} = sub { die "alarm\n" };
alarm 60;
$ua->get('https://secure.site.com'); #secure site that timed out
alarm 0;
} catch {
die $_ unless $_ eq "alarm\n";
print "page timed out after 60 seconds!\n";
exit;
};
my $total_time = sprintf '%.3f', ($ua->client_elapsed_time);
unless($ua->success){
print "Error: " . $ua->status;
exit;
}
...
I've gone over these questions to figure out how to get alarm to work without writing my own timeout function.
Perl Mechanize timeout not working with https and Ways to do timeouts in Perl?
So far I see recommendations for using LWPx::ParanoidAgent, not sure if I understand the "Use LWPx::ParanoidAgent and mix it into Mech" part
Possible to use timeout in WWW::Mechanize on https?
or patching LWP::UserAgent with
http://search.cpan.org/~sharyanto/LWP-UserAgent-Patch-HTTPSHardTimeout-0.04/lib/LWP/UserAgent/Patch/HTTPSHardTimeout.pm
Any thoughts on how to get the timeout to work with alarm?
Thanks!
回答1:
The below helped to set an alarm for each get()
, Seems much easier than try-catch with sig alarm
unless i'm missing something?
use Sys::SigAction qw(timeout_call);
if ( timeout_call( 60 ,sub { $ua->get('https://secured.site.com'); } ))
{
print "ALARM page timed out after 60 seconds!\n" ;
exit;
}
Pretty much the same answer as this question but with actual code Ways to do timeouts in Perl?
text from http://metacpan.org/pod/Sys::SigAction
timeout_call()
$timeout ,$coderef
Given a code reference, and a timeout value (in seconds), timeout() will (in an eval) setup a signal handler for SIGALRM (which will die), set an alarm clock, and execute the code reference. $time (seconds) may be expressed as a floating point number.
If Time::HiRes is present and useable, timeout_call() can be used with a timer resolution of 0.000001 seconds. If Time:HiRes is not available then factional second values less than 1.0 are tranparently converted to 1.
If the alarm goes off the code will be interrupted. The alarm is canceled if the code returns before the alarm is fired. The routine returns true if the code being executed timed out. (was interrupted). Exceptions thrown by the code executed are propagated out.
The original signal handler is restored, prior to returning to the caller.
If HiRes is not loadable, Sys::SigAction will do the right thing and convert
one last thing to consider/keep in mind:
use of Sys::SigAction::timeout_call unsafe?
来源:https://stackoverflow.com/questions/12964503/wwwmechanizetimed-https-timeout-does-not-work