1
# This program is copyright 2010-2011 Percona Inc.
2
# Feedback and improvements are welcome.
4
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
5
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
6
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8
# This program is free software; you can redistribute it and/or modify it under
9
# the terms of the GNU General Public License as published by the Free Software
10
# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar
11
# systems, you can issue `man perlgpl' or `man perlartistic' to read these
14
# You should have received a copy of the GNU General Public License along with
15
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
# Place, Suite 330, Boston, MA 02111-1307 USA.
17
# ###########################################################################
18
# Retry package $Revision: 7473 $
19
# ###########################################################################
23
use warnings FATAL => 'all';
24
use English qw(-no_match_vars);
25
use constant MKDEBUG => $ENV{MKDEBUG} || 0;
28
my ( $class, %args ) = @_;
32
return bless $self, $class;
36
# * try coderef: code to try; return true on success
37
# * wait coderef: code that waits in between tries
39
# * tries scalar: number of retries to attempt (default 3)
40
# * retry_on_die bool: retry try code if it dies (default no)
41
# * on_success coderef: code to call if try is successful
42
# * on_failure coderef: code to call if try does not succeed
43
# Retries the try code until either it returns true or we exhaust
44
# the number of retry attempts. The args are passed to the coderefs
45
# (try, wait, on_success, on_failure). If the try code dies, that's
46
# a final failure (no more retries) unless retry_on_die is true.
47
# Returns either whatever the try code returned or undef on failure.
49
my ( $self, %args ) = @_;
50
my @required_args = qw(try wait);
51
foreach my $arg ( @required_args ) {
52
die "I need a $arg argument" unless $args{$arg};
54
my ($try, $wait) = @args{@required_args};
55
my $tries = $args{tries} || 3;
58
while ( ++$tryno <= $tries ) {
59
MKDEBUG && _d("Retry", $tryno, "of", $tries);
62
$result = $try->(tryno=>$tryno);
65
if ( defined $result ) {
66
MKDEBUG && _d("Try code succeeded");
67
if ( my $on_success = $args{on_success} ) {
68
MKDEBUG && _d("Calling on_success code");
69
$on_success->(tryno=>$tryno, result=>$result);
75
MKDEBUG && _d("Try code died:", $EVAL_ERROR);
76
die $EVAL_ERROR unless $args{retry_on_die};
79
# Wait if there's more retries, else end immediately.
80
if ( $tryno < $tries ) {
81
MKDEBUG && _d("Try code failed, calling wait code");
82
$wait->(tryno=>$tryno);
86
MKDEBUG && _d("Try code did not succeed");
87
if ( my $on_failure = $args{on_failure} ) {
88
MKDEBUG && _d("Calling on_failure code");
96
my ($package, undef, $line) = caller 0;
97
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
98
map { defined $_ ? $_ : 'undef' }
100
print STDERR "# $package:$line $PID ", join(' ', @_), "\n";
105
# ###########################################################################
107
# ###########################################################################