How to run external command in parallel using AnyEvent and Perl
Asked Answered
I

1

6

I'm new to Perl 5 asynchronous processes and find it exciting that CPAN offers similar support that we can do in Node.js with AnyEvent, IO::Async, etc. However, the tutorial provides a few examples for complicated stuff. What I need is only to run an external system command in parallel using AnyEvent.

Am I doing it correctly in the example below to zip a number of files asynchronously? Please don't raise a concern about running the system command zip instead of using CPAN modules; the example is purely to demonstrate the idea of running an asynchronous process...

#!/bin/env perl
use strict; 
use AnyEvent;
use AnyEvent::Util;

my $s1    = time;

my $quit_program = AnyEvent->condvar(
    cb => sub {
        warn "Done async";
    }
);

my $result;
$quit_program->begin( sub { shift->send($result) } );

for my $file (@files) {
    $quit_program->begin;

    my $cv; $cv = run_cmd [qw(zip), "${file}.zip", $file],
                "<" , "/dev/null",
                ">" , "/dev/null",
                "2>", "/dev/null";

    $cv->cb (sub {
        shift->recv and die "command failed";

        # undef $cv;
        $quit_program->end;
    });
}

$quit_program->end;   # end loop
my $foo = $quit_program->recv;
say "Total elapsed time: ", time - $s1, " ms";
Idempotent answered 28/4, 2014 at 0:14 Comment(0)
J
3

I assume you mean AnyEvent::Util and not AnyEvent::Tool.

Otherwise, I haven't tried out your program, but it looks like a textbook example of using condvars and run_cmd to me. It certainly is close to what I would write myself (I am the author of AnyEvent), gets the tricky parts right (having an outer begin/end in case @files is empty), does error checking and so on.

So if you ask me, you actually did read the docs and used your knowledge to pass the exam :)

Jello answered 30/4, 2014 at 5:12 Comment(2)
Thanks Marc, fixed the module name. I have accepted your answer, however I do have one question... when I removed the begin/end inside the loop, it doesn't die with "command failed" when an error occurs. What would be causing it?Idempotent
Sorry to be so late. If you remove the begin/end inside the loop, the following recv call will instantly return (nothing to wait for) and your program will exit. This has the effect of your program not having a chance to report anything - the commands (probably) are run, but your program exits before an error can even be detected.Jello

© 2022 - 2024 — McMap. All rights reserved.