As long as your job fails and there are retries left, sleep and then
try the job again. We can write this as follows:
sub retry {
my $job = shift;
my $retries = shift || 1;
my $delay = shift || 1;
my $res;
sleep $delay while !($res = &$job) && --$retries;
return $res;
}
(I renamed $timeout to $delay, which more
accurately describes what it is. A timeout is usually the maximum
time that you're willing to let an operation proceed before
giving up and canceling it.)
Just to be safe, let's test our code with Test::More:
use Test::More tests => 5;
is( retry(sub{0}), 0
, "always-failing job fails 1 retry" );
is( retry(sub{0}, 2), 0
, "always-failing job fails 2 retries" );
is( retry(sub{1}, 0), 1
, "always-succeeding job succeeds regardless of retries" );
is( retry(mk_counter(), 1), 0
, "succeed-on-second job fails if given only 1 retry" );
is( retry(mk_counter(), 2), 1
, "succeed-on-second job succeeds if given 2 retries" );
# helper that makes fns that return 0 on 1st call, 1 on 2nd, ...
sub mk_counter {
my $i = 0;
sub { $i++ }
}
And the test results:
1..5
ok 1 - always-failing job fails 1 retry
ok 2 - always-failing job fails 2 retries
ok 3 - always-succeeding job succeeds regardless of retries
ok 4 - succeed-on-second job fails if given only 1 retry
ok 5 - succeed-on-second job succeeds if given 2 retries
Cheers, Tom
|