File Coverage

blib/lib/AnyEvent/Subprocess.pm
Criterion Covered Total %
statement 2 4 50.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 4 6 66.6


line stmt bran cond sub pod time code
1             package AnyEvent::Subprocess;
2             BEGIN {
3 17     17   1163814 $AnyEvent::Subprocess::VERSION = '1.102912';
4             }
5             # ABSTRACT: flexible, OO, asynchronous process spawning and management
6 17     17   31901 use Moose;
  0            
  0            
7             with 'AnyEvent::Subprocess::Job';
8              
9             our $VERSION;
10              
11             use AnyEvent::Subprocess::DefaultDelegates;
12              
13             use namespace::autoclean;
14              
15             __PACKAGE__->meta->make_immutable;
16              
17             1;
18              
19              
20              
21             =pod
22              
23             =head1 NAME
24              
25             AnyEvent::Subprocess - flexible, OO, asynchronous process spawning and management
26              
27             =head1 VERSION
28              
29             version 1.102912
30              
31             =head1 SYNOPSIS
32              
33             use AnyEvent::Subprocess;
34              
35             # prepare the job
36             my $job = AnyEvent::Subprocess->new(
37             delegates => ['StandardHandles'],
38             on_completion => sub { die 'bad exit status' unless $_[0]->is_success },
39             code => sub {
40             my %args = %{$_[0]};
41             while(<>){
42             print "Got line: $_";
43             }
44             exit 0;
45             },
46             );
47              
48             # start the child
49             my $run = $job->run;
50              
51             # add watcher to print the next line we see on the child's stdout
52             $run->delegate('stdout')->handle->push_read( line => sub {
53             my ($h, $line) = @_;
54             say "The child said: $line";
55             });
56              
57             # write to the child's stdin
58             $run->delegate('stdin')->handle->push_write("Hello, world!\n");
59              
60             # close stdin after it has been written to the child
61             $run->delegate('stdin')->handle->on_drain(sub { $_[0]->close_fh });
62              
63             # kill the child if it takes too long to produce a result
64             my $killer = AnyEvent->timer( after => 42, interval => 0, cb => sub {
65             $run->kill(2); # SIGINT.
66             });
67              
68             # ensure the event loop runs until the on_completion handler dies
69             EV::loop(); # you can use any AnyEvent-compatible event loop, including POE
70              
71             # eventually prints "The child said: Got line: Hello, world!", or
72             # perhaps dies if your system is really really overloaded.
73              
74             =head1 DESCRIPTION
75              
76             There are so many possible ways to use this module that a tutorial
77             would take me months to write. You should definitely read the test
78             suite to see what possibilities exist. (There is also an examples
79             directory in the dist.)
80              
81             The basic "flow" is like in the SYNOPSIS section; create a job, call
82             run, wait for your callback to be called with the exit status of the
83             subprocess.
84              
85             The fun comes when you add delegates.
86              
87             Delegates are technically instances of classes. Typing:
88              
89             my $stdin = AnyEvent::Subprocess::Job::Delegate::Handle->new(
90             name => 'stdin',
91             direction => 'w',
92             replace => \*STDIN,
93             );
94              
95             Every time you want to be able to write to STDIN is going to become
96             tiring after a while. When you load C<AnyEvent::Subprocess>, you also
97             load
98             L<AnyEvent::Subprocess::DefaultDelegate|AnyEvent::Subprocess::DefaultDelegates>.
99             This registers short names for each delegate and will cause
100             C<AnyEvent::Subprocess::Job> to build the actual instances
101             automatically. This means you can say C<'StandardHandles'> to get a
102             delegate for each of STDIN, STDOUT, and STDERR. If you want to know
103             how all the sugary names work, just open C<DefaultDelegates.pm> and
104             take a look. (The documentation for that module also covers that, as
105             well as how to define your own delegate builders.)
106              
107             If you are too lazy to look -- there are delegates for giving the
108             child arbitrary sockets or pipes opened to arbitrary file descriptors
109             (so you can deal with more than stdin/stdout/stderr and communicate
110             bidirectionally between the parent and child), there is a delegate for
111             giving the child a pseudo-tty (which can run complicatged programs,
112             like emacs!), there is a delegate for capturing any input
113             automatically, and passing it back to the parent via the C<Done>
114             object, and there is a delegate for calling functions in the parent
115             when certain events are received.
116              
117             Once you have decided what delegates your job needs, you need to
118             create a job object:
119              
120             my $proc = AnyEvent::Subprocess->new(
121             delegates => [qw/List them here/],
122             code => sub { code to run in the child },
123             on_completion => sub { code to run in the parent when the child is done },
124             );
125              
126             Then you can run it:
127              
128             my $running = $proc->run;
129             my $another = $proc->run({ with => 'args' }); # a separate process
130              
131             The C<code> coderef receives a hashref as an argument; delegates
132             typically populate this for you, but you can also pass a hashref of
133             args to run (that will be merged with any arguments the delegates
134             create; the delegates' arguments "win" if there is a conflict). The
135             code then runs in a child process until it stops running for some
136             reason. The C<on_completion> hook is then run in the parent, with the
137             L<AnyEvent::Subprocess::Done|AnyEvent::Subprocess::Done> object passed
138             in as an argument.
139              
140             You can, of course, have as many children running concurrently as you
141             desire. The event loop handles managing the any IO with the child,
142             and the notifications of the child dying. (You don't need to deal
143             with SIGCHLD or anything like that.)
144              
145             =head1 OVERVIEW
146              
147             C<AnyEvent::Subprocess> is a set of modules for running external
148             processes, and interacting with them in the context of an event-driven
149             program. It is similar to L<POE::Wheel::Run|POE::Wheel::Run>, but
150             much more customizable (and Moose-based). It is also similar to
151             modules that really want to be event-based, but aren't for some
152             reason; this includes L<IPC::Run|IPC::Run> and
153             L<IPC::Open3|IPC::Open3>, L<Expect|Expect>, and even the built-in
154             C<qx//> operator. You can replace all those modules with this one,
155             and have the ability to write much more flexible applications and
156             libraries.
157              
158             AnyEvent::Subprocess is based on three classes;
159             C<AnyEvent::Subprocess::Job>, which represents a job that can be run
160             at a later time, C<AnyEvent::Subprocess::Running>, which represents a
161             running child process, and C<AnyEvent::Subprocess::Done>, which
162             represents a completed job. The C<Job> object contains the command to
163             run, information about its environment (which handles to capture,
164             which plugins to run, what to do when the job is done, etc.). Then
165             C<Run> object is returned by C<< $job->run >>, and lets you interact
166             with the running subprocess. This includes things like writing to its
167             pipes/sockets, reading from its pipes, sending it signals, and so on.
168             When the running job exits, the C<on_completion> handler provided by
169             the Job object is called with a C<Done> object. This contains the
170             exit status, output that the process produced (if requested), and so
171             on.
172              
173             What makes this more interesting is the ability to add delegates to
174             any of these classes. These delegates are called into at various
175             points and allow you to add more features. By default, you just get a
176             callback when the process exits. You can also kill the running
177             process. That's it. From there, you can add delegates to add more
178             features. You can add a pipe to share between the parent and the
179             child. Instead of sharing a pipe, you can have an fd opened to an
180             arbitrary file descriptor number in the child. You have an infinite
181             number of these, so you can capture the child's stdout and stderr,
182             write to its stdin, and also share a socket for out-of-band
183             communication. You can also open a pipe to the child's fd #5 and
184             write to it. (This is nice if you are invoking something like C<gpg>
185             that wants the password written on an arbitrary fd other than 1.)
186              
187             (This is all done with the included C<Handle> delegate. See
188             L<AnyEvent::Subprocess::Job::Delegate::Handle>.)
189              
190             You can then build upon this; instead of writing your own code to
191             reading the handles when they become readable and accumulate input,
192             you can write a delegate that saves all the data coming from a given
193             handle and gives it to your program after the child exits (via the
194             C<Done> instance).
195              
196             (This is also included via the C<CaptureHandle> delegate. See
197             L<AnyEvent::Subprocess::Job::Delegate::CaptureHandle>.)
198              
199             All of this integrates into your existing event-based app; waiting for
200             IO from the child (or waiting for the child to exit) is asynchronous,
201             and lets your app do other work while waiting for the child. (It can
202             integrate nicely into Coro, for example, unlike the default C<qx//>.)
203              
204             =head1 BUGS
205              
206             The parent's event loop still exists in the child process, which means
207             you can't safely use it in the child. I have tried to work around
208             this in a few event loops; my C<AnyEventX::Cancel> module on github is
209             an early attempt. When that becomes stable, I will remove this
210             restriction.
211              
212             In the mean time, YOU MUST NOT USE ANY EVENT-LOOP FUNCTIONS IN THE
213             CHILD.
214              
215             This is not a problem if you are running external processes, but is a
216             problem if you are running a code block and you want to do event-ful
217             things in there. (Note that EV is designed to allow the child to
218             handle events that the parent created watchers for. You can do that
219             just fine. It's if you want a fresh event loop with no existing
220             watchers that doesn't work well yet.)
221              
222             =head1 AUTHOR
223              
224             Jonathan Rockway <jrockway@cpan.org>
225              
226             =head1 COPYRIGHT AND LICENSE
227              
228             This software is copyright (c) 2011 by Jonathan Rockway.
229              
230             This is free software; you can redistribute it and/or modify it under
231             the same terms as the Perl 5 programming language system itself.
232              
233             =cut
234              
235              
236             __END__
237