File Coverage

blib/lib/Paws/API/Retry.pm
Criterion Covered Total %
statement 30 32 93.7
branch 8 10 80.0
condition 6 6 100.0
subroutine 9 10 90.0
pod 0 5 0.0
total 53 63 84.1


line stmt bran cond sub pod time code
1             package Paws::API::Retry;
2 12     12   102451 use Moose;
  12         643227  
  12         94  
3 12     12   86657 use MooseX::ClassAttribute;
  12         115367  
  12         107  
4 12     12   467530 use Paws::Exception;
  12         60  
  12         9226  
5              
6             class_has default_rules => (is => 'ro', isa => 'ArrayRef', default => sub { [
7             #general_socket_errors
8             sub { $_[0]->code eq 'ConnectionError' },
9             #general_server_error
10             sub { defined $_[0]->http_status and $_[0]->http_status == 500 },
11             #service_unavailable
12             sub { defined $_[0]->http_status and $_[0]->http_status == 503 },
13             #limit_exceeded"
14             sub { defined $_[0]->http_status and $_[0]->http_status == 509 },
15             #throttling_exception
16             sub { defined $_[0]->http_status and $_[0]->http_status == 400 and $_[0]->code eq 'ThrottlingException' },
17             #throttling
18             sub { defined $_[0]->http_status and $_[0]->http_status == 400 and $_[0]->code eq 'Throttling' },
19             #too_many_requests
20             sub { defined $_[0]->http_status and $_[0]->http_status == 429 },
21             ] });
22              
23             has max_tries => (is => 'ro', required => 1);
24             has type => (is => 'ro', required => 1);
25              
26             has tries => (is => 'rw', default => 0);
27              
28             has retry_rules => (is => 'ro', required => 1);
29              
30             has error_for_die => (is => 'rw');
31             has operation_result => (is => 'rw');
32              
33             has generator => (is => 'ro');
34              
35             around BUILDARGS => sub {
36             my ($orig, $class, %args) = @_;
37              
38             if ($args{ type } eq 'exponential') {
39             $args{ generator } = sub {
40             my $self = shift;
41             (2 ** ($self->tries - 2)) + (rand(1) / 2);
42             };
43             } else {
44             die "Don't know how to make a retry type of $args{ type }";
45             }
46              
47             return $class->$orig(%args);
48             };
49              
50             sub should_retry {
51 233     233 0 3109 my $self = shift;
52 233         7836 my $res = $self->operation_result;
53              
54 233 100 100     911 if ($self->result_is_exception and $self->_still_has_retries and $self->exception_is_retriable){
      100        
55 53         451 return 1;
56             }
57 180         996 return 0; #Anything not exception should not be retried
58             }
59              
60             sub exception_is_retriable {
61 116     116 0 334 my $self = shift;
62              
63             #Try default_rules, and then the Service's retriables
64 116         252 foreach my $rule (@{ Paws::API::Retry->default_rules }, @{ $self->retry_rules }){
  116         3389  
  116         2839  
65 566 100       12899 return 1 if ($rule->($self->operation_result));
66             }
67             }
68              
69             sub result_is_exception {
70 322     322 0 611 my $self = shift;
71              
72 322 50       7867 die "Don't have an operation_result set yet" if (not defined $self->operation_result);
73              
74 322 50       7531 return 0 if (not ref($self->operation_result)); # Scalar results
75 322 100       7582 return 1 if (ref($self->operation_result) eq 'Paws::Exception'); # Exceptions
76 156         568 return 0; # Rest of objects
77             }
78            
79             sub one_more_try {
80 119     119 0 1843 my $self = shift;
81 119         3196 $self->tries($self->tries + 1);
82             }
83            
84             sub sleep_time {
85 31     31 0 211 my $self = shift;
86 31         897 return $self->generator->($self);
87             }
88              
89             sub _still_has_retries {
90 129     129   394 my $self = shift;
91 129         3489 $self->tries < $self->max_tries;
92             }
93            
94             sub _is_retriable {
95 0     0     my $self = shift;
96             # TODO: evaluate if the error is retriable depending on class definition
97 0           return 1;
98             }
99            
100             __PACKAGE__->meta->make_immutable;
101            
102             1;