当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《LWP::UserAgent请求方法的真正超时》经验,为你挑选了1个好方法。

我正在尝试向不可靠的服务器实现请求.请求是一个很好的,但我的perl脚本不能100%成功完成.问题是服务器偶尔会死锁(我们试图找出原因)并且请求永远不会成功.由于服务器认为它是活动的,它会使套接字连接保持打开状态,因此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;
    }
}

Stephen Deke.. 12

您可以尝试LWPx :: ParanoidAgent,LWP :: UserAgent的子类,它对如何与远程Web服务器交互更加谨慎.

除此之外,它还允许您指定全局超时.它由Brad Fitzpatrick开发,作为LiveJournal项目的一部分.



1> Stephen Deke..:

您可以尝试LWPx :: ParanoidAgent,LWP :: UserAgent的子类,它对如何与远程Web服务器交互更加谨慎.

除此之外,它还允许您指定全局超时.它由Brad Fitzpatrick开发,作为LiveJournal项目的一部分.

推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有