cheshirecat has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I'm having major problems with LWP and timeouts.
As it stands, my cgi script is making a request of a 3rd party site which occasionally takes more than 10 seconds to fufill.
What I want to do is cancel the request if it takes longer than 3 seconds (it usually completes in this time but sometimes not).
Here's a code snippet, any comments welcome

my $timeout = 3 my $timedout = 0; my $oops = 0; my $error; my $stime; my $etime; eval { local $SIG{ALRM} = sub { die "timeout\n" }; # die out of eval + statement not entire program alarm $timeout; $stime = time; # make a note of the time now $result = $ua->request($req); # make request of website $etime = time; # make a note of the time now alarm 0; }; if ($@) { if ($@ eq "timeout\n") { $timedout = 1; } if ($@ and $@ ne "timeout\n") { $oops = 1; } # if there was an erro +r in the eval and it wasn't the alarm } $error = $timedout || $oops; my $dtime = $etime - $stime; # figure out the time taken for the requ +est if (!$error) { open(TEST,">/var/tmp/t4.txt"); print TEST "http result\n"; # here I get told that the request took 10 seconds and my time out is +3 seconds print TEST $result->status_line." : $dtime secs taken, timeout = $ti +meout\n"; # print TEST "ok\n"; close(TEST); } else { open(TEST,">/var/tmp/t4.txt"); if ($oops) { print TEST "oops error occurred: $@\n"; } else { print TEST "timeout\n";} close(TEST); }
Cheers Cheshire Cat

Replies are listed 'Best First'.
Re: Problems trying to timeout LWP requests
by rob_au (Abbot) on Feb 06, 2002 at 12:25 UTC
    There's a much easier way to do this - You can set the timeout for the connection by calling the timeout method on your LWP::UserAgent object.

    For example:

    my $ua = LWP::UserAgent->new; $ua->timeout(3); # Sets a three-second timeout

    By default, this timeout method is set to 180 seconds (3 minutes) - This is described in the LWP documentation. Additionally, the use_alarm method can be used to set/get a value indicating whether to use alarm when implementing timeouts - This is useful if you make use of alarm elsewhere in your applications.

     

    perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'

        The request is working and the host is responding okay but for purposes of testing the timeout I have chosen a value sufficiently low that the request should be cancelled anyway.

        I have looked at the results of Super Search and I believe this is a common question to which nobody has been able to give a satisfactory answer.

        I have now emailed Gisle Aas to see if he can throw any light on the question.

        Cheers

        Cheshire Cat

      I've tried using $ua->timeout(3); and it does not work for me,
      this was why I was trying the alarm method.

      As for use_alarm, see the code below from UserAgent.pm

      # depreciated sub use_eval { shift->_elem('use_eval', @_); } sub use_alarm { Carp::carp("LWP::UserAgent->use_alarm(BOOL) is a no-op") if @_ > 1 && $^W; ""; }

      It appears that the documentation is out of date as this method is now depreciated.

      Cheers

      Cheshire Cat

Re: Problems trying to timeout LWP requests
by cheshirecat (Sexton) on Feb 06, 2002 at 12:18 UTC
    Hi again, Forgot to say, running on Solaris with LWP 5.63 Cheers Cheshire Cat