AnyEvent-Sub-Retry
view release on metacpan or search on metacpan
lib/AnyEvent/Sub/Retry.pm view on Meta::CPAN
use parent qw/Exporter/;
use AnyEvent;
our @EXPORT = qw/retry/;
sub retry {
my ( $retry_count, $retry_interval, $code_ref ) = @_;
my $all_cv = AE::cv;
my $timer;
my $try;
$try = sub {
my $cv = eval { $code_ref->() };
if ($@) {
undef $try;
$all_cv->croak( sprintf( "code_ref died with message:%s", $@ ) );
return;
}
unless ( $cv && ref($cv) eq 'AnyEvent::CondVar' ) {
lib/AnyEvent/Sub/Retry.pm view on Meta::CPAN
sprintf( "code_ref does not return condvar ref:%s", ref($cv) )
);
return;
}
$cv->cb(
sub {
my @vals = eval { shift->recv };
if ($@) {
$retry_count--;
if ( $retry_count > 0 ) {
$timer = AnyEvent->timer(
cb => sub { $try->(); undef $timer; },
after => $retry_interval,
);
}
else {
undef $try;
$all_cv->croak($@);
}
}
else {
undef $try;
t/01-retry.t view on Meta::CPAN
use AnyEvent::Sub::Retry;
subtest 'no retry' => sub {
subtest 'success' => sub {
my $call_count = 0;
my $t;
my $code_ref = sub {
$call_count ++;
my $cv = AE::cv;
$t = AnyEvent->timer(cb => sub { $cv->send('foo', 'var') });
return $cv;
};
my $cv = retry 1, 1, $code_ref;
is_deeply([$cv->recv], ['foo', 'var']);
is $call_count, 1;
};
subtest 'failure' => sub {
my $call_count = 0;
my $t;
my $code_ref = sub {
$call_count ++;
my $cv = AE::cv;
$t = AnyEvent->timer(cb => sub { $cv->croak('oh no!') });
return $cv;
};
my $cv = retry 1, 1, $code_ref;
eval { $cv->recv; };
like $@, qr/oh no!/;
is $call_count, 1;
};
subtest 'croaked' => sub {
my $call_count = 0;
t/01-retry.t view on Meta::CPAN
};
};
subtest 'with retry' => sub {
my $call_count = 0;
my $t;
my $code_ref = sub {
$call_count ++;
my $cv = AE::cv;
my $should_return_success = $call_count == 1 ? 0 : 1;
$t = AnyEvent->timer(
cb => sub {
if ($should_return_success) {
$cv->send('foo', 'var');
} else {
$cv->croak('error!');
}
}
);
return $cv;
};
t/02-leak.t view on Meta::CPAN
use AnyEvent::Sub::Retry;
use Test::LeakTrace;
my $call_count = 0;
my $t;
my $now = AnyEvent->time;
my $code_ref = sub {
$call_count ++;
my $cv = AE::cv;
my $should_return_success = $call_count == 1 ? 0 : 1;
$t = AnyEvent->timer(
cb => sub {
if ($should_return_success) {
$cv->send('foo', 'var');
} else {
$cv->croak('error!');
}
}
);
return $cv;
};
( run in 0.974 second using v1.01-cache-2.11-cpan-49f99fa48dc )