gpt4 book ai didi

perl - LWP::UserAgent 请求方法的真正超时

转载 作者:行者123 更新时间:2023-12-04 00:59:40 27 4
gpt4 key购买 nike

我正在尝试向不可靠的服务器发出请求。这个请求很好,但不是 100% 需要我的 perl 脚本成功完成。问题是服务器偶尔会死锁(我们正在尝试找出原因)并且请求永远不会成功。由于服务器认为它是事件的,它保持套接字连接打开,因此 LWP::UserAgent 的超时值对我们没有任何好处。对请求强制执行绝对超时的最佳方法是什么?

仅供引用,这不是 DNS 问题。死锁与大量更新同时命中我们的 Postgres 数据库有关。出于测试目的,我们基本上在服务器响应处理程序中放置了一个 while(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;
}
}

最佳答案

你可以试试 LWPx::ParanoidAgent ,LWP::UserAgent 的一个子类,它对如何与远程网络服务器交互更加谨慎。
除此之外,它允许您指定全局超时。它由 Brad Fitzpatrick 作为 LiveJournal 项目的一部分开发。

关于perl - LWP::UserAgent 请求方法的真正超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73308/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com