4

我正在使用 LWP 从网页下载内容,我想限制它等待页面的时间。

my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
$response = $ua->get("http://XML File");
$content = $response->decoded_content;

问题是服务器偶尔会死锁(我们正试图找出原因)并且请求永远不会成功。由于服务器认为它是活动的,它保持套接字连接打开,因此 LWP::UserAgent 的超时值对我们没有任何好处。对请求强制执行绝对超时的最佳方法是什么?

每当超时达到其限制时,它就会死掉,我无法继续使用脚本!整个脚本处于一个循环中,它必须按顺序获取 XML 文件。我真的很想正确处理这个超时并使脚本继续到下一个地址。有谁知道如何做到这一点?谢谢!!

4

2 回答 2

8

我之前在https://stackoverflow.com/a/10318268/1331451中遇到过类似的问题。

您需要做的是添加一个$SIG{ALRM}处理程序并使用alarm它来调用它。您在拨打电话之前设置好,alarm然后直接取消它。然后您可以查看返回的 HTTP::Result。

警报将触发信号,Perl 将调用信号处理程序。在其中,您可以直接执行操作,也可以die仅执行die. 这eval是为了die不破坏整个程序。如果调用信号处理程序,alarm则会自动重置。

您还可以向处理程序添加不同die的消息,然后$@像@larsen 在他的回答中所说的那样进行区分。

这是一个例子:

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new;
my $res;
eval {
  # custom timeout (strace shows EAGAIN)
  # see https://stackoverflow.com/a/10318268/1331451
  local $SIG{ALRM} = sub {
    # This is where it dies
    die "Timeout occured...";
  }; # NB: \n required
  alarm 10;
  $res = $ua->request($req);
  alarm 0;
};
if ($res && $res->is_success) {
  # the result was a success
}
于 2013-04-09T11:08:30.327 回答
0

一般来说,eval如果你想捕获和控制可能死掉的代码部分,你可以使用一个块。

while( … ) { # this is your main loop
    eval {
        # here the code that can die
    };
    if ($@) {
        # if something goes wrong, the special variable $@ 
        # contains the error message (as a string or as a blessed reference,
        # it depends on how the invoked code threats the exception.
    }
}

您可以在 eval 函数的文档中找到更多信息

于 2013-04-09T11:09:18.870 回答