NAME
Try::Tiny::Retry - Extends Try::Tiny to allow retries
VERSION
version 0.003
SYNOPSIS
Use just like Try::Tiny, but with "retry" instead of "try". By default,
"retry" will try 10 times with exponential backoff:
use Try::Tiny::Retry;
retry { ... }
catch { ... }
finally { ... };
You can retry only if the error matches some conditions:
use Try::Tiny::Retry;
retry { ... }
retry_if { /^could not connect/ }
catch { ... };
You can customize the number of tries and delay timing:
use Try::Tiny::Retry ':all';
retry { ... }
delay_exp { 5, 1e6 } # 5 tries, 1 second exponential-backoff
catch { ... };
You can run some code before each retry:
use Try::Tiny::Retry;
retry { ... }
on_retry { ... }
catch { ... };
DESCRIPTION
This module extends Try::Tiny to allow for retrying a block of code
several times before failing. Otherwise, it works seamlessly like
Try::Tiny.
By default, Try::Tiny::Retry exports "retry" and "retry_if", plus "try",
"catch" and "finally" from Try::Tiny. You can optionally export "delay"
or "delay_exp". Or you can get everything with the ":all" tag.
FUNCTIONS
retry
retry { ... } # code that might fail
retry_if { ... } # conditions to be met for a retry
delay { ... } # control repeats and intervals between retries
catch { ... }; # handler if all retries fail
The "retry" function works just like "try" from Try::Tiny, except that
if an exception is thrown, the block may be executed again, depending on
the "retry_if" and "delay" blocks.
If one or more "retry_if" blocks are provided, as long as any of them
evaluate to true, a retry will be attempted unless the result of the
"delay" block indicates otherwise. If none of them evaluate to true, no
retry will be attempted and the "delay" block will not be called.
If no "delay" block is provided, the default will be 10 tries with a
random delay up to 100 milliseconds with an exponential backoff. (See
"delay_exp".) This has an expected cumulative delay of around 25 seconds
if all retries fail.
retry_if
retry { ... }
retry_if { /^could not connect/ }
catch { ... };
A "retry_if" block controls whether a retry should be attempted after an
exception (assuming there are any retry attempts remaining).
The block is passed the cumulative number of attempts as an argument.
The exception caught is provided in $_, just as with "catch". It should
return a true value if a retry should be attempted.
Multiple "retry_if" blocks may be provided. Only one needs to evaluate
to true to enable a retry.
Using a "retry_if" block based on the retry count is an alternate way to
allow fewer (but not greater) tries than the default "delay" function,
but with the default exponential backoff behavior. These are effectively
equivalent:
retry { ... }
retry_if { shift() < 3 };
retry { ... }
delay_exp { 3, 1e5 };
If you wish the exception to be rethrown if all "retry_if" blocks return
false, you must use a "catch" block to do so:
retry { ... }
retry_if { /^could not connect/ }
catch { die $_ };
on_retry
retry { ... }
on_retry { $state->reset() }
catch { ... };
The "on_retry" block runs before each "retry" block after the first
attempt. The block is passed the cumulative number of attempts as an
argument. The return value is ignored.
Only one "on_retry" block is allowed.
delay
retry { ... }
delay {
return if $_[0] >= 3; # only three tries
sleep 1; # constant delay between tries
}
catch { ... };
The "delay" block controls the number of attempts and the delay between
attempts.
The block is passed the cumulative number of attempts as an argument. If
the "delay" block returns an undefined value, no further retries will be
made.
If you wish the exception to be rethrown if all attempts fail, you must
use a "catch" block to do so:
retry { ... }
delay { ... }
catch { die $_ };
Only one "delay" block is allowed.
delay_exp
retry { ... }
delay_exp { 3, 10000 } # 3 tries, 10000 µsec
catch { ... };
This function is an exponential-backoff delay-function generator. The
delay between attempts is randomly selected between 0 and an upper
bound. The upper bound doubles after each failure.
It requires a code block as an argument. The block will be evaluated in
list context and must return two elements. The first element is the
number of tries allowed. The second element is the starting upper bound
in microseconds.
Given number of tries "N" and upper bound "U", the expected cumulative
delay time if all attempts fail is "0.5 * U * ( 2^(N-1) - 1 )".
SEE ALSO
There are other retry modules on CPAN, but none of them worked
seamlessly with Try::Tiny.
* Action::Retry — OO (Moo) or functional; various delay strategies;
supports conditions
* AnyEvent::Retry — OO (Moose) and event-driven; various delay
strategies
* Attempt — functional; simple retry count with constant sleep time
* Retry — OO (Moose) with fixed exponential backoff; supports
callbacks on every iteration
* Sub::Retry — functional; simple retry count with constant sleep
time; supports conditions
SUPPORT
Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker at
<https://github.com/dagolden/Try-Tiny-Retry/issues>. You will be
notified automatically of any progress on your issue.
Source Code
This is open source software. The code repository is available for
public review and contribution under the terms of the license.
<https://github.com/dagolden/Try-Tiny-Retry>
git clone https://github.com/dagolden/Try-Tiny-Retry.git
AUTHOR
David Golden <dagolden@cpan.org>
CONTRIBUTOR
David Steinbrunner <dsteinbrunner@pobox.com>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2013 by David Golden.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004