MojoX::Run - asynchronous external command or subroutine execution for Mojo


NAME

MojoX::Run - asynchronous external command or subroutine execution for Mojo


SYNOPSIS

 # create executor object
 # NOTE: new *ALWAYS* returns singleton object!
 my $executor = MojoX::Run->new()
 
 # simple usage
 my $pid = $executor->spawn(
        cmd => "ping -W 2 -c 5 host.example.org",
        exit_cb => sub {
                my ($pid, $res) = @_;
                print "Ping finished with exit status $res->{exit_val}.\n";
                print "\tSTDOUT:\n$res->{stdout}\n";
                print "\tSTDERR:\n$res->{stderr}\n";
        }
 );
 # check for injuries
 unless ($pid) {
        print "Command startup failed: ", $executor->error(), "\n";
 }
 
 # more complex example...
 my $pid2 = $executor->spawn(
        cmd => 'ping host.example.org',
        stdin_cb => sub {
                my ($pid, $chunk) = @_;
                print "STDOUT $pid: '$chunk'\n"
        },
        # ignore stderr
        stderr_cb => sub {},
        exit_cb => sub {
                my ($pid, $res) = @_;
                print "Process $res->{cmd} [pid: $pid] finished after $res->{time_duration_exec} second(s).\n";
                print "Exit status: $res->{exit_status}";
                print " by signal $res->{exit_signal}" if ($res->{exit_signal});
                print "with coredump " if ($res->{exit_core});
                print "\n";
        }
 );
 
 # even fancier usage: spawn coderef
 my $pid3 = $executor->spawn(
        cmd => sub {
                for (my $i = 0; $i < 10; $i++) {
                        if (rand() > 0.5) {
                                print STDERR rand(), "\n"
                        } else {
                                print rand(), "\n";
                        }
                        sleep int(rand(10));
                }
                exit (rand() > 0.5) ? 0 : 1;
        },
        exit_cb => {
                print "Sub exited with $res->{exit_status}, STDOUT: $res->{stdout}\n";
        },
 );


OBJECT CONSTRUCTOR

new ()

Constructor doesn't accept any arguments and ALWAYS returns singleton instance.


METHODS

error ()

Returns last error.

spawn (%opt)

Spawns new subprocess. The following options are supported:

cmd (string/arrayref/coderef, undef, required):

Command to be started. Command can be simple scalar, array reference or perl CODE reference if you want to custom perl subroutine asynchronously.

stdout_cb (coderef, undef):

Code that will be invoked when data were read from processes's stdout. If omitted, stdout output will be returned as argument to exit_cb. Example:

 stdout_cb => sub {
        my ($pid, $data) = @_;
        print "Process $pid stdout: $data";
 }
stderr_cb (coderef, undef):

Code that will be invoked when data were read from processes's stderr. If omitted, stderr output will be returned as argument to exit_cb. Example:

 stderr_cb => sub {
        my ($pid, $data) = @_;
        print "Process $pid stderr: $data";
 }
stdin_cb (coderef, undef):

Code that will be invoked when data wrote to process's stdin were flushed. Example:

 stdin_cb => sub {
        my ($pid) = @_;
        print "Process $pid: stdin was flushed.";
 }
exit_cb (coderef, undef, required)

Code to be invoked after process exits and all handles have been flushed. Function is called with 2 arguments: Process identifier (pid) and result structure. Example:

 exit_cb => sub {
        my ($pid, $res) = @_;
        print "Process $pid exited\n";
        print "Execution error: $res->{error}\n" if (defined $res->{error});
        print "Exit status: $pid->{exit_status}\n";
        print "Killed by signal $pid->{exit_signal}\n" if ($res->{exit_signal});
        print "Process dumped core.\n" if (res->{exit_core});
        print "Process was started at: $res->{time_started}\n";
        print "Process exited at $res->{time_stopped}\n";
        print "Process execution duration: $res->{time_duration_exec}\n";
        print "Execution duration: $res->{time_duration_total}\n";
        print "Process stdout: $res->{stdout}\n";
        print "Process stderr: $res->{stderr}\n";
 }
exec_timeout (float, 0):

If set to positive non-zero value, process will be killed after specified timeout of seconds. Timeout accuracy depends on IOLoop's timeout() value (Default is 0.25 seconds).

Returns non-zero process identifier (pid) on success, otherwise 0 and sets error.

stdin_write ($pid, $data [, $cb])

Writes $data to stdin of process $pid if process still has opened stdin. If $cb is defined code reference it will invoke it when data has been written. If $cb is omitted stdin_cb will be invoked if is set for process $pid.

Returns 1 on success, otherwise 0 and sets error.

stdout_cb ($pid [, $cb])

If called without $cb argument returns stdout callback for process $pid, otherwise sets stdout callback. If $cb is undefined, removes callback.

Returns undef on error and sets error message.

stderr_cb ($pid [, $cb])

If called without $cb argument returns stderr callback for process $pid, otherwise sets stderr callback. If $cb is undefined, removes callback.

Returns undef on error and sets error message.

stdin_cb ($pid [, $cb])

If called without $cb argument returns stdin callback for process $pid, otherwise sets stdin callback. If $cb is undefined, removes callback.

Returns undef on error and sets error message.

stdin_close ($pid)

Closes stdin handle to specified process. You need to explicitly close stdin if spawned program doesn't exit until it's stdin is not closed.

stdout_buf ($pid)

Returns contents of stdout buffer for process $pid on success, otherwise undef.

stdout_buf_clear ($pid)

Clears stdout buffer for process $pid. Returns empty string on success, otherwise undef.

stderr_buf ($pid)

Returns contents of stderr buffer for process $pid on success, otherwise undef.

stderr_buf_clear ($pid)

Clears stderr buffer for process $pid. Returns empty string on success, otherwise undef.

kill ($pid [, $signal = 15])

Kills process $pid with specified signal. Returns 1 on success, otherwise 0.

log_level ([$level])

Gets or sets loglevel for private logger instance. See the Mojo::Log manpage for additional instructions.


AUTHOR

"Brane F. Gracnar", <"bfg at frost.ath.cx">


BUGS

Please report any bugs or feature requests to bug-mojox-run at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc MojoX::Run

You can also look for information at:


ACKNOWLEDGEMENTS

This module was inspired by the POE::Wheel::Run manpage by Rocco Caputo; module includes patched version of the IPC::Open3 manpage from Perl distribution which allows perl coderef execution.


LICENSE AND COPYRIGHT

Copyright 2010, Brane F. Gracnar.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

 MojoX::Run - asynchronous external command or subroutine execution for Mojo