Hi All I have been developing relatively simple perl programs on and off over the years, mainly for integrations using synchronous operations. I have since been tasked with building a "simple" ICMP and SNMP polling engine (yes re-inventing the wheel...) to allow for asynchronous/parallel polling. In researching the various options, i have learnt of the event loop options in perl. AnyEvent, IO:Async etc. Given AnyEvent has Ping and SNMP modules I have started using these and learning the ropes of AnyEvent. In testing the use cases required for the solution, I need to be able to ping different sets of hosts on different timers. So I have started developing the below code. The problem I am having is i'm getting the "AnyEvent::CondVar: recursive blocking wait attempted" error. I understand why, $cv_ping->recv; is blocking the event loop. However I am not how I work around this, or if my approach is actually going to work as I don't have much experience with AnyEvent. I have trawled the interwebs for various materials and tried different things but haven't been able to get it to work. My code is below, help/advice is much appreciated.
use strict; use AnyEvent; use AnyEvent::Ping; use IO::Async::Timer::Periodic; use IO::Async::Loop; use Data::Dumper; my @todoList = map { "192.168.100." . $_ } (1 .. 254); my $ping_timeout=2; #seconds to wait for response my $ping_attemps=4; #number of pings to issue, my $ping_pktsize=32; #packet size of ping my $start_run = time(); main(); sub main{ my $loop = IO::Async::Loop->new; my $timer = IO::Async::Timer::Periodic->new( interval => 5, first_interval => 2, reschedule => 'hard', on_tick => sub { print "before ping\n"; \&ping_hosts(@todoList); print "after ping\n"; }, ); my $timer2 = IO::Async::Timer::Periodic->new( interval => 7, first_interval => 2, reschedule => 'hard', on_tick => sub { print "before ping2\n"; \&ping_hosts(@todoList); print "after ping2\n"; }, ); $timer->start; $timer2->start; $loop->add( $timer ); $loop->add( $timer2 ); $loop->run; } sub ping_hosts{ my @hosts=@_; my $callback=shift; my $result; my $cv_ping = AnyEvent->condvar; my $ping = AnyEvent::Ping->new(packet_size => $ping_pktsize); $ping->timeout($ping_timeout); #$cv_ping->begin(sub { shift->send($_[0]) }); foreach my $host (@hosts) { $cv_ping->begin; my $request; $request = $ping->ping($host, $ping_attemps, sub { print "\n$host state:".Dumper($_[0]); undef $request; $cv_ping->end; }); } $cv_ping->recv; $cv_ping->end; #$cv_ping->cb(sub { $_[0]->recv }); $ping->end; }
In reply to Implementing AnyEvent::Ping multiple times by mmoorreett
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |