.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "LWP::UserAgent::Determined 3pm" .TH LWP::UserAgent::Determined 3pm "2022-10-13" "perl v5.34.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" LWP::UserAgent::Determined \- a virtual browser that retries errors .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& use strict; \& use LWP::UserAgent::Determined; \& my $browser = LWP::UserAgent::Determined\->new; \& my $response = $browser\->get($url, headers... ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This class works just like LWP::UserAgent (and is based on it, by being a subclass of it), except that when you use it to get a web page but run into a possibly-temporary error (like a \s-1DNS\s0 lookup timeout), it'll wait a few seconds and retry a few times. .PP It also adds some methods for controlling exactly what errors are considered retry-worthy and how many times to wait and for how many seconds, but normally you needn't bother about these, as the default settings are relatively sane. .SH "METHODS" .IX Header "METHODS" This module inherits all of LWP::UserAgent's methods, and adds the following. .ie n .IP "$timing_string = $browser\->\fBtiming()\fR;" 4 .el .IP "\f(CW$timing_string\fR = \f(CW$browser\fR\->\fBtiming()\fR;" 4 .IX Item "$timing_string = $browser->timing();" .PD 0 .ie n .IP "$browser\->timing( ""10,30,90"" )" 4 .el .IP "\f(CW$browser\fR\->timing( ``10,30,90'' )" 4 .IX Item "$browser->timing( 10,30,90 )" .PD The \f(CW\*(C`timing\*(C'\fR method gets or sets the string that controls how many times it should retry, and how long the pauses should be. .Sp If you specify empty-string, this means not to retry at all. .Sp If you specify a string consisting of a single number, like \*(L"10\*(R", that means that if the first request doesn't succeed, then \&\f(CW\*(C`$browser\->get(...)\*(C'\fR (or any other method based on \f(CW\*(C`request\*(C'\fR or \f(CW\*(C`simple_request\*(C'\fR) should wait 10 seconds and try again (and if that fails, then it's final). .Sp If you specify a string with several numbers in it (like \*(L"10,30,90\*(R"), then that means \f(CW$browser\fR can \fIre\fRtry as that many times (i.e., one initial try, \fIplus\fR a maximum of the three retries, because three numbers there), and that it should wait first those numbers of seconds each time. So \f(CW\*(C`$browser\->timing( "10,30,90" )\*(C'\fR basically means: .Sp .Vb 7 \& try the request; return it unless it\*(Aqs a temporary\-looking error; \& sleep 10; \& retry the request; return it unless it\*(Aqs a temporary\-looking error; \& sleep 30; \& retry the request; return it unless it\*(Aqs a temporary\-looking error; \& sleep 90 the request; \& return it; .Ve .Sp The default value is \*(L"1,3,15\*(R". .ie n .IP "$http_codes_hr = $browser\->\fBcodes_to_determinate()\fR;" 4 .el .IP "\f(CW$http_codes_hr\fR = \f(CW$browser\fR\->\fBcodes_to_determinate()\fR;" 4 .IX Item "$http_codes_hr = $browser->codes_to_determinate();" This returns the hash that is the set of \s-1HTTP\s0 codes that merit a retry (like 500 and 408, but unlike 404 or 200). You can delete or add entries like so; .Sp .Vb 3 \& $http_codes_hr = $browser\->codes_to_determinate(); \& delete $http_codes_hr\->{408}; \& $http_codes_hr\->{567} = 1; .Ve .Sp (You can actually set a whole new hashset with \f(CW\*(C`$browser\->codes_to_determinate($new_hr)\*(C'\fR, but there's usually no benefit to that as opposed to the above.) .Sp The current default is 408 (Timeout) plus some 5xx codes. .ie n .IP "$browser\->\fBbefore_determined_callback()\fR" 4 .el .IP "\f(CW$browser\fR\->\fBbefore_determined_callback()\fR" 4 .IX Item "$browser->before_determined_callback()" .PD 0 .ie n .IP "$browser\->before_determined_callback( \e&some_routine );" 4 .el .IP "\f(CW$browser\fR\->before_determined_callback( \e&some_routine );" 4 .IX Item "$browser->before_determined_callback( &some_routine );" .ie n .IP "$browser\->\fBafter_determined_callback()\fR" 4 .el .IP "\f(CW$browser\fR\->\fBafter_determined_callback()\fR" 4 .IX Item "$browser->after_determined_callback()" .ie n .IP "$browser\->after_determined_callback( \e&some_routine );" 4 .el .IP "\f(CW$browser\fR\->after_determined_callback( \e&some_routine );" 4 .IX Item "$browser->after_determined_callback( &some_routine );" .PD These read (first two) or set (second two) callbacks that are called before the actual HTTP/FTP/etc request is made. By default, these are set to undef, meaning nothing special is called. If you want to alter try requests, or inspect responses before any retrying is considered, you can set up these callbacks. .Sp The arguments passed to these routines are: .RS 4 .ie n .IP "0: the current $browser object" 4 .el .IP "0: the current \f(CW$browser\fR object" 4 .IX Item "0: the current $browser object" .PD 0 .ie n .IP "1: an arrayref to the list of timing pauses (based on $browser\->timing)" 4 .el .IP "1: an arrayref to the list of timing pauses (based on \f(CW$browser\fR\->timing)" 4 .IX Item "1: an arrayref to the list of timing pauses (based on $browser->timing)" .IP "2: the duration of the number of seconds we'll pause if this request fails this time, or undef if this is the last chance." 4 .IX Item "2: the duration of the number of seconds we'll pause if this request fails this time, or undef if this is the last chance." .ie n .IP "3: the value of $browser\->codes_to_determinate" 4 .el .IP "3: the value of \f(CW$browser\fR\->codes_to_determinate" 4 .IX Item "3: the value of $browser->codes_to_determinate" .IP "4: an arrayref of the arguments we pass to LWP::UserAgent::simple_request (the first of which is the request object)" 4 .IX Item "4: an arrayref of the arguments we pass to LWP::UserAgent::simple_request (the first of which is the request object)" .IP "(5): And, only for after_determined_callback, the response we just got." 4 .IX Item "(5): And, only for after_determined_callback, the response we just got." .RE .RS 4 .PD .Sp Example use: .Sp .Vb 3 \& $browser\->before_determined_callback( sub { \& print "Trying ", $_[4][0]\->uri, " ...\en"; \& }); .Ve .RE .SH "IMPLEMENTATION" .IX Header "IMPLEMENTATION" This class works by overriding LWP::UserAgent's \f(CW\*(C`simple_request\*(C'\fR method with its own around-method that just loops. See the source of this module; it's straightforward. Relatively. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\s-1LWP\s0, LWP::UserAgent .SH "COPYRIGHT AND DISCLAIMER" .IX Header "COPYRIGHT AND DISCLAIMER" Copyright 2004, Sean M. Burke, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .PP This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. .SH "AUTHOR" .IX Header "AUTHOR" Originally created by Sean M. Burke, \f(CW\*(C`sburke@cpan.org\*(C'\fR .PP Currently maintained by Jesse Vincent \f(CW\*(C`jesse@fsck.com\*(C'\fR