我試圖實現一個不可靠的服務器的請求。該請求是一個很好的,但我的Perl腳本不能100%成功完成。問題在於服務器偶爾會發生死鎖(我們試圖弄清楚原因),並且請求永遠不會成功。由於服務器認爲它是活動的,因此它保持套接字連接打開,因此LWP :: UserAgent的超時值對我們來說沒有好處。對請求執行絕對超時的最佳方式是什麼?LWP :: UserAgent請求方法的真正超時
僅供參考,這不是DNS問題。這個僵局與大量更新同時觸發我們的Postgres數據庫有關。出於測試目的,我們已經在服務器響應處理程序中放了一段時間(1){}行。
目前,代碼看起來像這樣:
my $ua = LWP::UserAgent->new;
ua->timeout(5); $ua->cookie_jar({});
my $req = HTTP::Request->new(POST => "http://$host:$port/auth/login");
$req->content_type('application/x-www-form-urlencoded');
$req->content("login[user]=$username&login[password]=$password");
# This line never returns
$res = $ua->request($req);
我一直在使用信號觸發超時嘗試過,但似乎並沒有工作。
eval {
local $SIG{ALRM} = sub { die "alarm\n" };
alarm(1);
$res = $ua->request($req);
alarm(0);
};
# This never runs
print "here\n";
最終的答案,我將使用脫機被提出的一個人,但我會在這裏提到它。出於某種原因,SigAction可以工作,而$ SIG(ALRM)則不可以。仍然不知道爲什麼,但這已經過測試,以工作。這裏有兩個工作版本:
# Takes a LWP::UserAgent, and a HTTP::Request, returns a HTTP::Request
sub ua_request_with_timeout {
my $ua = $_[0];
my $req = $_[1];
# Get whatever timeout is set for LWP and use that to
# enforce a maximum timeout per request in case of server
# deadlock. (This has happened.)
use Sys::SigAction qw(timeout_call);
our $res = undef;
if(timeout_call(5, sub {$res = $ua->request($req);})) {
return HTTP::Response->new(408); #408 is the HTTP timeout
} else {
return $res;
}
}
sub ua_request_with_timeout2 {
print "ua_request_with_timeout\n";
my $ua = $_[0];
my $req = $_[1];
# Get whatever timeout is set for LWP and use that to
# enforce a maximum timeout per request in case of server
# deadlock. (This has happened.)
my $timeout_for_client = $ua->timeout() - 2;
our $socket_has_timedout = 0;
use POSIX;
sigaction SIGALRM, new POSIX::SigAction(
sub {
$socket_has_timedout = 1;
die "alarm timeout";
}
) or die "Error setting SIGALRM handler: $!\n";
my $res = undef;
eval {
alarm ($timeout_for_client);
$res = $ua->request($req);
alarm(0);
};
if ($socket_has_timedout) {
return HTTP::Response->new(408); #408 is the HTTP timeout
} else {
return $res;
}
}
的可能的複製[如何執行在Perl明確超時?](http://stackoverflow.com/questions/15899855/how-to-enforce-a -definite-timeout-in-perl) – sixtyfootersdude 2016-02-24 22:51:45