File Coverage

blib/lib/LWP/UserAgent/Plugin/Retry.pm
Criterion Covered Total %
statement 14 60 23.3
branch 0 32 0.0
condition 0 21 0.0
subroutine 5 6 83.3
pod 0 1 0.0
total 19 120 15.8


line stmt bran cond sub pod time code
1             package LWP::UserAgent::Plugin::Retry;
2              
3 1     1   304074 use 5.010001;
  1         3  
4 1     1   4 use strict;
  1         2  
  1         28  
5 1     1   3 use warnings;
  1         1  
  1         553  
6 1     1   1647 use Log::ger;
  1         46  
  1         5  
7              
8 1     1   640 use Time::HiRes qw(sleep);
  1         1142  
  1         5  
9              
10             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
11             our $DATE = '2024-07-17'; # DATE
12             our $DIST = 'LWP-UserAgent-Plugin-Retry'; # DIST
13             our $VERSION = '0.005'; # VERSION
14              
15             sub after_request {
16 0     0 0   my ($class, $r) = @_;
17              
18             $r->{config}{max_attempts} //=
19 0   0       $ENV{LWP_USERAGENT_PLUGIN_RETRY_MAX_ATTEMPTS} // 4;
      0        
20             $r->{config}{delay} //=
21 0   0       $ENV{LWP_USERAGENT_PLUGIN_RETRY_DELAY} // 2;
      0        
22 0 0         if (defined $r->{config}{strategy}) {
23 0           require Module::Load::Util;
24             $r->{ua}{_backoff_obj} //=
25             Module::Load::Util::instantiate_class_with_optional_args(
26 0   0       {ns_prefix => 'Algorithm::Backoff'}, $r->{config}{strategy});
27             }
28              
29 0           my $is_success;
30 0           my $code = $r->{response}->code;
31 0 0         if (defined $r->{config}{retry_if}) {
32 0           my $ref = ref $r->{config}{retry_if};
33 0 0 0       if ($ref eq 'Regexp' or !$ref) {
    0          
    0          
34 0 0         $is_success++ unless $code =~ $r->{config}{retry_if};
35             } elsif ($ref eq 'ARRAY') {
36 0 0         $is_success++ unless grep { $_ == $code } @{ $r->{config}{retry_if} };
  0            
  0            
37             } elsif ($ref eq 'CODE') {
38 0 0         $is_success++ unless $r->{config}{retry_if}->($class, $r);
39             } else {
40 0           die "Please supply a scalar/Regexp/arrayref/coderef retry_if";
41             }
42             } else {
43 0 0         $is_success++ if $code !~ /\A[5]/;
44             }
45              
46             SUCCESS: {
47 0 0         last unless $is_success;
  0            
48 0 0         if ($r->{ua}{_backoff_obj}) {
49 0           my $delay_on_success = $r->{ua}{_backoff_obj}->success;
50 0 0         if ($delay_on_success > 0) {
51 0           log_trace "Delaying for %.1f second(s) after successful request", $delay_on_success;
52 0           sleep $delay_on_success;
53             }
54             }
55 0           return -1;
56             }
57              
58 0   0       $r->{retries} //= 0;
59 0           my $max_attempts;
60             my $delay;
61 0           my $should_give_up;
62 0 0         if ($r->{ua}{_backoff_obj}) {
63 0           $delay = $r->{ua}{_backoff_obj}->failure;
64 0 0         $should_give_up++ if $delay < 0;
65 0           $max_attempts = $r->{ua}{_backoff_obj}{max_attempts};
66             } else {
67             $should_give_up++ if $r->{config}{max_attempts} &&
68 0 0 0       1+$r->{retries} >= $r->{config}{max_attempts};
69 0           $max_attempts = $r->{config}{max_attempts};
70 0           $delay = $r->{config}{delay};
71             }
72              
73 0           my ($ua, $request) = @{ $r->{argv} };
  0            
74              
75             GIVE_UP: {
76 0 0         last unless $should_give_up;
  0            
77             log_trace "Failed requesting %s %s (%s - %s), giving up",
78             $request->method,
79             $request->uri . "",
80             $r->{response}->code,
81 0           $r->{response}->message;
82 0           return 0;
83             }
84              
85 0           $r->{retries}++;
86              
87             log_trace "Failed requesting %s %s (%s - %s), retrying in %.1f second(s) (attempt %d of %d) ...",
88             $request->method,
89             $request->uri . "",
90             $r->{response}->code,
91             $r->{response}->message,
92             $delay,
93             1+$r->{retries},
94 0           $max_attempts;
95 0           sleep $delay;
96 0           98; # repeat request()
97             }
98              
99             1;
100             # ABSTRACT: Retry failed requests
101              
102             __END__