perlevent-handlinganyevent

Perl Anyevent , non blocking redis push


I have the code below to do non blocking rpush into a redis server When I run this for just 1 rpush , the code works fine But when I run this in a while loop the script hangs after the first execution. Why ?

#!/usr/bin/perl                                                                                                                                                          
use AnyEvent;
use AnyEvent::Redis::RipeRedis;
use strict;
#my $cv = AE::cv();                                                                                                                                                      

my $redis = AnyEvent::Redis::RipeRedis->new(
  host     => 'localhost',
  port     => '6379',
    );

my $i=0;

my $cv;
while($i++ < 5) {
    $cv = AnyEvent->condvar;
    $redis->rpush( 'list', "1","2","3",
                   { on_done => sub {
                   my $data = shift;
                   print "$data\n";
                     },
                   }
        );
    $cv->recv();
}
$redis->quit(
    sub {$cv->send();}
    );
$cv->recv();

Solution

  • You block script execution when you call $cv->recv() in while loop and script are waiting $cv->send or $cv->croak, but in callback you don't call $cv->send().

    $cv->recv

    Wait (blocking if necessary) until the ->send or ->croak methods have been called on $cv, while servicing other watchers normally.

    If you want to send different not blocking requestes try to use AnyEvents begin and end methods.

    #!/usr/bin/perl
    use AnyEvent;
    use AnyEvent::Redis::RipeRedis;
    use strict;
    
    my $redis = AnyEvent::Redis::RipeRedis->new(
      host     => 'localhost',
      port     => '6379',
    );
    
    my $i=0;
    
    my  $cv = AnyEvent->condvar;
    while($i++ < 5) {
       $cv->begin;
       $redis->rpush( 'list', "1","2","3",
                   { 
                      on_done => sub {
                        my $data = shift;
                        print "$data\n";
                        $cv->end();
                      },
                   }
        );
    }
    
    $cv->recv();