App-AlgorithmBackoffUtils
view release on metacpan or search on metacpan
lib/App/AlgorithmBackoffUtils.pm view on Meta::CPAN
{url => 'pm:Algorithm::Backoff::LIMD'},
],
};
sub retry_limd {
_retry("LIMD", {@_});
}
$SPEC{retry_mild} = {
v => 1.1,
summary => 'Retry a command with MILD (multiplicative increase, linear decrease) backoff',
args => {
%args_retry_common,
%{ $Algorithm::Backoff::MILD::SPEC{new}{args} },
},
features => {
dry_run => 1,
},
links => [
{url => 'pm:Algorithm::Backoff::MILD'},
],
};
sub retry_mild {
_retry("MILD", {@_});
}
$SPEC{retry_mimd} = {
v => 1.1,
summary => 'Retry a command with MIMD (multiplicative increase, multiplicative decrease) backoff',
args => {
%args_retry_common,
%{ $Algorithm::Backoff::MIMD::SPEC{new}{args} },
},
features => {
dry_run => 1,
},
links => [
{url => 'pm:Algorithm::Backoff::MIMD'},
],
};
sub retry_mimd {
_retry("MIMD", {@_});
}
$SPEC{show_backoff_delays} = {
v => 1.1,
summary => 'Show backoff delays',
args => {
%arg_algorithm,
%args_algo_attrs,
logs => {
summary => 'List of failures or successes',
schema => ['array*', of=>'str*', 'x.perl.coerce_rules'=>['From_str::comma_sep']],
'x.name.is_plural' => 1,
'x.name.singular' => 'log',
req => 1,
pos => 0,
slurpy => 1,
description => <<'_',
A list of 0's (to signify failure) or 1's (to signify success). Each
failure/success can be followed by `:TIMESTAMP` (unix epoch) or `:+SECS` (number
of seconds after the previous log), or the current timestamp will be assumed.
Examples:
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
(10 failures followed by 5 successes).
0 0:+2 0:+4 0:+6 1
(4 failures, 2 seconds apart, followed by immediate success.)
_
},
},
features => {
dry_run => 1,
},
links => [
{url => 'pm:Algorithm::Backoff::Fibonacci'},
],
};
sub show_backoff_delays {
my %args = @_;
my $algo = $args{algorithm} or return [400, "Please specify algorithm"];
my $algo_args = ${"Algorithm::Backoff::$algo\::SPEC"}{new}{args};
my %algo_attrs;
for my $arg (keys %args_algo_attrs) {
my $argspec = $args_algo_attrs{$arg};
next unless grep {
$_ eq 'category:common-to-all-algorithms' ||
$_ eq lc("category:$algo-algorithm")
} @{ $argspec->{tags} };
if (exists $args{$arg}) {
$algo_attrs{$arg} = $args{$arg};
}
}
#use DD; dd \%args_algo_attrs;
#use DD; dd \%algo_attrs;
my $ab = "Algorithm::Backoff::$algo"->new(%algo_attrs);
my @delays;
my $time = time();
my $i = 0;
for my $log (@{ $args{logs} }) {
$i++;
$log =~ /\A([01])(?::(\+)?(\d+))?\z/ or
return [400, "Invalid log#$i syntax '$log', must be 0 or 1 followed by :TIMESTAMP or :+SECS"];
if ($2) {
$time += $3;
} elsif (defined $3) {
$time = $3;
}
my $delay;
if ($1) {
$delay = $ab->success($time);
} else {
$delay = $ab->failure($time);
}
lib/App/AlgorithmBackoffUtils.pm view on Meta::CPAN
again right after the previous failure() (i.e. specify the same timestamp).
failure() will then return ~2+2 = 4 seconds. On the other hand, if you waited 2
seconds before calling failure() again (i.e. specify the timestamp that is 2
seconds larger than the previous timestamp), failure() will return 2 seconds.
And if you waited 4 seconds or more, failure() will return 0.
=item * B<delay> => I<ufloat>
Number of seconds to wait after a failure.
=item * B<delay_increment_on_failure> => I<float>
How much to add to previous delay, in seconds, upon failure (e.g. 5).
=item * B<delay_increment_on_success> => I<float>
How much to add to previous delay, in seconds, upon success (e.g. -5).
=item * B<delay_multiple_on_failure> => I<ufloat>
How much to multiple previous delay, upon failure (e.g. 1.5).
=item * B<delay_multiple_on_success> => I<ufloat>
How much to multiple previous delay, upon success (e.g. 0.5).
=item * B<delay_on_success> => I<ufloat> (default: 0)
Number of seconds to wait after a success.
=item * B<exponent_base> => I<ufloat> (default: 2)
=item * B<initial_delay> => I<ufloat>
Initial delay for the first attempt after failure, in seconds.
=item * B<initial_delay1> => I<ufloat>
Initial delay for the first attempt after failure, in seconds.
=item * B<initial_delay2> => I<ufloat>
Initial delay for the second attempt after failure, in seconds.
=item * B<jitter_factor> => I<float>
How much to add randomness.
If you set this to a value larger than 0, the actual delay will be between a
random number between original_delay * (1-jitter_factor) and original_delay *
(1+jitter_factor). Jitters are usually added to avoid so-called "thundering
herd" problem.
The jitter will be applied to delay on failure as well as on success.
=item * B<logs>* => I<array[str]>
List of failures or successes.
A list of 0's (to signify failure) or 1's (to signify success). Each
failure/success can be followed by C<:TIMESTAMP> (unix epoch) or C<:+SECS> (number
of seconds after the previous log), or the current timestamp will be assumed.
Examples:
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
(10 failures followed by 5 successes).
0 0:+2 0:+4 0:+6 1
(4 failures, 2 seconds apart, followed by immediate success.)
=item * B<max_actual_duration> => I<ufloat> (default: 0)
Maximum number of seconds for all of the attempts (0 means unlimited).
If set to a positive number, will limit the number of seconds for all of the
attempts. This setting is used to limit the amount of time you are willing to
spend on a task. For example, when using the Exponential strategy of
initial_delay=3 and max_attempts=10, the delays will be 3, 6, 12, 24, ... If
failures are logged according to the suggested delays, and max_actual_duration
is set to 21 seconds, then the third failure() will return -1 instead of 24
because 3+6+12 >= 21, even though max_attempts has not been exceeded.
=item * B<max_attempts> => I<uint> (default: 0)
Maximum number consecutive failures before giving up.
0 means to retry endlessly without ever giving up. 1 means to give up after a
single failure (i.e. no retry attempts). 2 means to retry once after a failure.
Note that after a success, the number of attempts is reset (as expected). So if
max_attempts is 3, and if you fail twice then succeed, then on the next failure
the algorithm will retry again for a maximum of 3 times.
=item * B<max_delay> => I<ufloat>
Maximum delay time, in seconds.
=item * B<min_delay> => I<ufloat> (default: 0)
Maximum delay time, in seconds.
=back
Special arguments:
=over 4
=item * B<-dry_run> => I<bool>
Pass -dry_run=E<gt>1 to enable simulation mode.
=back
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code
(200 means OK, 4xx caller error, 5xx function error). Second element
(msg) is a string containing error message, or 'OK' if status is
200. Third element (payload) is optional, the actual result. Fourth
( run in 1.425 second using v1.01-cache-2.11-cpan-39bf76dae61 )