Graham Ollis > AnyEvent-Open3-Simple-0.79 > AnyEvent::Open3::Simple

Download:
AnyEvent-Open3-Simple-0.79.tar.gz

Dependencies

Annotate this POD

Website

View/Report Bugs
Module Version: 0.79   Source   Latest Release: AnyEvent-Open3-Simple-0.80

NAME ^

AnyEvent::Open3::Simple - Interface to open3 under AnyEvent

VERSION ^

version 0.79

SYNOPSIS ^

 use v5.10;
 use AnyEvent;
 use AnyEvent::Open3::Simple;
 
 my $done = AnyEvent->condvar;
 
 my $ipc = AnyEvent::Open3::Simple->new(
   on_start => sub {
     my $proc = shift;       # isa AnyEvent::Open3::Simple::Process
     my $program = shift;    # string
     my @args = @_;          # list of arguments
     say 'child PID: ', $proc->pid;
   },
   on_stdout => sub { 
     my $proc = shift;       # isa AnyEvent::Open3::Simple::Process
     my $line = shift;       # string
     say 'out: ', $string;
   },
   on_stderr => sub {
     my $proc = shift;       # isa AnyEvent::Open3::Simple::Process
     my $line = shift;       # string
     say 'err: ', $line;
   },
   on_exit   => sub {
     my $proc = shift;       # isa AnyEvent::Open3::Simple::Process
     my $exit_value = shift; # integer
     my $signal = shift;     # integer
     say 'exit value: ', $exit_value;
     say 'signal:     ', $signal;
     $done->send;
   },
   on_error => sub {
     my $error = shift;      # the exception thrown by IPC::Open3::open3
     my $program = shift;    # string
     my @args = @_;          # list of arguments
     warn "error: $error";
     $done->send;
   },
 );
 
 $ipc->run('echo', 'hello there');
 $done->recv;

DESCRIPTION ^

This module provides an interface to open3 while running under AnyEvent that delivers data from stdout and stderr as lines are written by the subprocess. The interface is reminiscent of IPC::Open3::Simple, although this module does provides a somewhat different API, so it cannot be used a drop in replacement for that module.

There are already a number of interfaces for interacting with subprocesses in the context of AnyEvent, but this one is the most convenient for my usage. Note the modules listed in the SEE ALSO section below for other interfaces that may be more or less appropriate.

CONSTRUCTOR ^

Constructor takes a hash or hashref of event callbacks and attributes. Event callbacks have an on_ prefix, attributes do not.

ATTRIBUTES

EVENTS

These events will be triggered by the subprocess when the run method is called. Each event callback (except on_error) gets passed in an instance of AnyEvent::Open3::Simple::Process as its first argument which can be used to get the PID of the subprocess, or to write to it. on_error does not get a process object because it indicates an error in the creation of the process.

Not all of these events will fire depending on the execution of the child process. In the very least exactly one of on_start or on_error will be called.

METHODS ^

run

 $ipc->run($program, @arguments);
 $ipc->run($program, @arguments, \$stdin);
 $ipc->run($program, @arguments, \@stdin);

Start the given program with the given arguments. Returns immediately. Any events that have been specified in the constructor (except for on_start) will not be called until the process re-enters the event loop.

You may optionally provide the full content of standard input as a string reference or list reference as the last argument. If provided as a list reference, it will be joined by new lines in whatever format is native to your Perl. Currently on (non cygwin) Windows (Strawberry, ActiveState) this is the only way to provide standard input to the subprocess.

Do not mix the use of passing standard input to run and AnyEvent::Open3::Simple::Process#print or AnyEvent::Open3::Simple::Process#say, otherwise bad things may happen.

CAVEATS ^

Some AnyEvent implementations may not work properly with the method used by AnyEvent::Open3::Simple to wait for the child process to terminate. See "CHILD-PROCESS-WATCHERS" in AnyEvent for details.

This module uses an idle watcher instead of a child watcher to detect program termination on Microsoft Windows (but not Cygwin). This is because the child watchers are unsupported by AnyEvent on Windows. The idle watcher implementation seems to pass the test suite, but there may be some traps for the unwary. There may be other platforms or event loops where this is the appropriate choice, and you can use the ANYEVENT_OPEN3_SIMPLE environment variable or the implementation attribute to force it use an idle watcher instead. Patches for detecting environments where idle watchers should be used are welcome and encouraged.

The pure perl implementation that comes with AnyEvent (AnyEvent::Impl::Perl) does not seem to work with this module on Microsoft Windows so I make EV a prereq on that platform (which is automatically used if installed and does work).

Writing to a subprocesses stdin with AnyEvent::Open3::Simple::Process#print or AnyEvent::Open3::Simple::Process#say is unsupported on Microsoft Windows (it does work under Cygwin though).

There are some traps for the unwary relating to buffers and deadlocks, IPC::Open3 is recommended reading.

If you register a call back for on_exit, but not on_error then use a condition variable to wait for the process to complete as in this:

 my $cv = AnyEvent->condvar;
 my $ipc = AnyEvent::Open3::Simple->new(
   on_exit => sub { $cv->send },
 );
 $ipc->run('command_not_found');
 $cv->recv;

You might be waiting forever if there is an error starting the process (if for example you give it a bad command). To handle this situation you might use croak on the condition variable in the event of error:

 my $cv = AnyEvent->condvar;
 my $ipc = AnyEvent::Open3::Simple->new(
   on_exit => sub { $cv->send },
   on_error => sub {
     my $error = shift;
     $cv->croak($error);
   },
 );
 $ipc->run('command_not_found');
 $cv->recv;

This will cause the recv to die, printing a useful diagnostic if the exception isn't caught somewhere else.

SEE ALSO ^

AnyEvent::Subprocess, AnyEvent::Util, AnyEvent::Run.

AUTHOR ^

author: Graham Ollis <plicease@cpan.org>

contributors:

Stephen R. Scaffidi

COPYRIGHT AND LICENSE ^

This software is copyright (c) 2012 by Graham Ollis.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

syntax highlighting: