AnyEvent-Subprocess
view release on metacpan or search on metacpan
lib/AnyEvent/Subprocess.pm view on Meta::CPAN
}
# ABSTRACT: flexible, OO, asynchronous process spawning and management
use Moose;
with 'AnyEvent::Subprocess::Job';
our $VERSION;
use AnyEvent::Subprocess::DefaultDelegates;
use namespace::autoclean;
__PACKAGE__->meta->make_immutable;
1;
=pod
=head1 NAME
AnyEvent::Subprocess - flexible, OO, asynchronous process spawning and management
=head1 VERSION
version 1.102912
=head1 SYNOPSIS
use AnyEvent::Subprocess;
# prepare the job
my $job = AnyEvent::Subprocess->new(
delegates => ['StandardHandles'],
on_completion => sub { die 'bad exit status' unless $_[0]->is_success },
code => sub {
my %args = %{$_[0]};
while(<>){
print "Got line: $_";
}
exit 0;
},
);
# start the child
my $run = $job->run;
# add watcher to print the next line we see on the child's stdout
$run->delegate('stdout')->handle->push_read( line => sub {
my ($h, $line) = @_;
say "The child said: $line";
});
# write to the child's stdin
$run->delegate('stdin')->handle->push_write("Hello, world!\n");
# close stdin after it has been written to the child
$run->delegate('stdin')->handle->on_drain(sub { $_[0]->close_fh });
# kill the child if it takes too long to produce a result
my $killer = AnyEvent->timer( after => 42, interval => 0, cb => sub {
$run->kill(2); # SIGINT.
});
# ensure the event loop runs until the on_completion handler dies
EV::loop(); # you can use any AnyEvent-compatible event loop, including POE
# eventually prints "The child said: Got line: Hello, world!", or
# perhaps dies if your system is really really overloaded.
=head1 DESCRIPTION
There are so many possible ways to use this module that a tutorial
would take me months to write. You should definitely read the test
suite to see what possibilities exist. (There is also an examples
directory in the dist.)
The basic "flow" is like in the SYNOPSIS section; create a job, call
run, wait for your callback to be called with the exit status of the
subprocess.
The fun comes when you add delegates.
Delegates are technically instances of classes. Typing:
my $stdin = AnyEvent::Subprocess::Job::Delegate::Handle->new(
name => 'stdin',
direction => 'w',
replace => \*STDIN,
);
Every time you want to be able to write to STDIN is going to become
tiring after a while. When you load C<AnyEvent::Subprocess>, you also
load
L<AnyEvent::Subprocess::DefaultDelegate|AnyEvent::Subprocess::DefaultDelegates>.
This registers short names for each delegate and will cause
C<AnyEvent::Subprocess::Job> to build the actual instances
automatically. This means you can say C<'StandardHandles'> to get a
delegate for each of STDIN, STDOUT, and STDERR. If you want to know
how all the sugary names work, just open C<DefaultDelegates.pm> and
take a look. (The documentation for that module also covers that, as
well as how to define your own delegate builders.)
If you are too lazy to look -- there are delegates for giving the
child arbitrary sockets or pipes opened to arbitrary file descriptors
(so you can deal with more than stdin/stdout/stderr and communicate
bidirectionally between the parent and child), there is a delegate for
giving the child a pseudo-tty (which can run complicatged programs,
like emacs!), there is a delegate for capturing any input
automatically, and passing it back to the parent via the C<Done>
object, and there is a delegate for calling functions in the parent
when certain events are received.
Once you have decided what delegates your job needs, you need to
create a job object:
my $proc = AnyEvent::Subprocess->new(
delegates => [qw/List them here/],
code => sub { code to run in the child },
on_completion => sub { code to run in the parent when the child is done },
);
( run in 0.311 second using v1.01-cache-2.11-cpan-02777c243ea )