Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AnyEvent fork_call and ping

I'm trying to create a perl module that pings (using the linux system ping) to hundreds of hosts, and get the data of the ping (like packet loss and how much packets transmitted and how much received and etc.) from the stdout of each host. I used AnyEvent::Util fork_call, but I got stuck as it doesn't collect the stdout. I've created a small script that demonstrates what i'm trying to do:

#!/usr/bin/perl
use strict;
use warnings;

use AnyEvent;
use AnyEvent::Util 'fork_call';
use DDP;

my $cv = AE::cv;

my @hosts = ( 'google.com', 'xkcd.com', 'pastebin.com', 'youtube.com' );

sub fork_ping {
    my $interval        = 0.2;
    my $source_address  = '1.1.1.1';
    my $number_of_pings = 5;
    my $timeout         = 5;

    my %ret_val;

    foreach my $host (@hosts) {
        $cv->begin;
        fork_call {
            my $stdout = `ping -c $number_of_pings -I $source_address -i $interval -W $timeout $host 2>&1`;
            return $stdout;
        } sub {
            $ret_val{$host} = shift;
            $cv->end;
        };
    }

    return \%ret_val;
}


my $timer = AE::timer 0, 5, sub {

    my $ping_data = fork_ping();
    p $ping_data;
};

$cv->recv;

Where have I got wrong?

like image 404
Adamba4 Avatar asked Oct 24 '25 13:10

Adamba4


1 Answers

You need to wait for the pings to finish ($cv->recv;) before you can print their output.

my $ping_data = fork_ping();
$cv->recv;
p $ping_data;

(You could also place the $cv->recv; inside of fork_ping.)

like image 96
ikegami Avatar answered Oct 27 '25 08:10

ikegami