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 )