Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
The command or code to run in the child process (as per the C<spawn> method)
=item on_finish => CODE
A continuation to be called when the child process exits and has closed all of
the filehandles that were set up for it. It will be invoked in the following
way:
$on_finish->( $pid, $exitcode )
The second argument is passed the plain perl C<$?> value.
=item on_error => CODE
Optional continuation to be called when the child code block throws an
exception, or the command could not be C<exec(2)>ed. It will be invoked in the
following way (as per C<spawn>)
$on_error->( $pid, $exitcode, $dollarbang, $dollarat )
If this continuation is not supplied, then C<on_finish> is used instead. The
value of C<$!> and C<$@> will not be reported.
=item setup => ARRAY
Optional reference to an array to pass to the underlying C<spawn> method.
=back
In addition, the hash takes keys that define how to set up file descriptors in
the child process. (If the C<setup> array is also given, these operations will
be performed after those specified by C<setup>.)
=over 8
=item fdI<n> => HASH
A hash describing how to set up file descriptor I<n>. The hash may contain one
of the following sets of keys:
=over 4
=item on_read => CODE
The child will be given the writing end of a pipe. The reading end will be
wrapped by an L<IO::Async::Stream> using this C<on_read> callback function.
=item from => STRING
The child will be given the reading end of a pipe. The string given by the
C<from> parameter will be written to the child. When all of the data has been
written the pipe will be closed.
=back
=item stdin => ...
=item stdout => ...
=item stderr => ...
Shortcuts for C<fd0>, C<fd1> and C<fd2> respectively.
=back
=cut
sub open_child
{
my $self = shift;
my %params = @_;
my $on_finish = delete $params{on_finish};
ref $on_finish or croak "Expected 'on_finish' to be a reference";
$params{on_finish} = sub {
my ( $process, $exitcode ) = @_;
$on_finish->( $process->pid, $exitcode );
};
if( my $on_error = delete $params{on_error} ) {
ref $on_error or croak "Expected 'on_error' to be a reference";
$params{on_exception} = sub {
my ( $process, $exception, $errno, $exitcode ) = @_;
# Swap order
$on_error->( $process->pid, $exitcode, $errno, $exception );
};
}
$params{on_exit} and croak "Cannot pass 'on_exit' parameter through ChildManager->open";
require IO::Async::Process;
my $process = IO::Async::Process->new( %params );
$self->add( $process );
return $process->pid;
}
=head2 run_child
$pid = $loop->run_child( %params )
This creates a new child process to run the given code block or command,
capturing its STDOUT and STDERR streams. When the process exits, a
continuation is invoked being passed the exitcode, and content of the streams.
=over 8
=item command => ARRAY or STRING
=item code => CODE
The command or code to run in the child process (as per the C<spawn_child>
method)
=item on_finish => CODE
A continuation to be called when the child process exits and closed its STDOUT
and STDERR streams. It will be invoked in the following way:
$on_finish->( $pid, $exitcode, $stdout, $stderr )
The second argument is passed the plain perl C<$?> value.
=item stdin => STRING
Optional. String to pass in to the child process's STDIN stream.
=item setup => ARRAY
Optional reference to an array to pass to the underlying C<spawn> method.
=back
This method is intended mainly as an IO::Async-compatible replacement for the
perl C<readpipe> function (`backticks`), allowing it to replace
my $output = `command here`;
with
$loop->run_child(
command => "command here",
on_finish => sub {
my ( undef, $exitcode, $output ) = @_;
...
}
);
=cut
sub run_child
{
my $self = shift;
my %params = @_;
my $on_finish = delete $params{on_finish};
ref $on_finish or croak "Expected 'on_finish' to be a reference";
my $stdout;
my $stderr;
my %subparams;
if( my $child_stdin = delete $params{stdin} ) {
ref $child_stdin and croak "Expected 'stdin' not to be a reference";
$subparams{stdin} = { from => $child_stdin };
}
$subparams{code} = delete $params{code};
$subparams{command} = delete $params{command};
$subparams{setup} = delete $params{setup};
croak "Unrecognised parameters " . join( ", ", keys %params ) if keys %params;
require IO::Async::Process;
my $process = IO::Async::Process->new(
%subparams,
stdout => { into => \$stdout },
stderr => { into => \$stderr },
on_finish => sub {
my ( $process, $exitcode ) = @_;
$on_finish->( $process->pid, $exitcode, $stdout, $stderr );
},
);
$self->add( $process );
return $process->pid;
}
=head2 resolver
$loop->resolver
Returns the internally-stored L<IO::Async::Resolver> object, used for name
resolution operations by the C<resolve>, C<connect> and C<listen> methods.
=cut
sub resolver
{
my $self = shift;
return $self->{resolver} ||= do {
require IO::Async::Resolver;
my $resolver = IO::Async::Resolver->new;
$self->add( $resolver );
$resolver;
}
}
=head2 set_resolver
$loop->set_resolver( $resolver )
Sets the internally-stored L<IO::Async::Resolver> object. In most cases this
method should not be required, but it may be used to provide an alternative
resolver for special use-cases.
=cut
sub set_resolver
{
my $self = shift;
my ( $resolver ) = @_;
$resolver->can( $_ ) or croak "Resolver is unsuitable as it does not implement $_"
for qw( resolve getaddrinfo getnameinfo );
$self->{resolver} = $resolver;
$self->add( $resolver );
}
=head2 resolve
@result = $loop->resolve( %params )->get
This method performs a single name resolution operation. It uses an
internally-stored L<IO::Async::Resolver> object. For more detail, see the
C<resolve> method on the L<IO::Async::Resolver> class.
( run in 1.296 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )