view release on metacpan or search on metacpan
local/lib/perl5/IO/Async.pm view on Meta::CPAN
The following sections describe particular types of Notifier.
=head2 File Handle IO
An L<IO::Async::Handle> object is a Notifier that represents a single IO handle
being managed. While in most cases it will represent a single filehandle, such
as a socket (for example, an L<IO::Socket::INET> connection), it is possible
to have separate reading and writing handles (most likely for a program's
C<STDIN> and C<STDOUT> streams, or a pair of pipes connected to a child
process).
The L<IO::Async::Stream> class is a subclass of L<IO::Async::Handle> which
maintains internal incoming and outgoing data buffers. In this way, it
implements bidirectional buffering of a byte stream, such as a TCP socket. The
class automatically handles reading of incoming data into the incoming buffer,
and writing of the outgoing buffer. Methods or callbacks are used to inform
when new incoming data is available, or when the outgoing buffer is empty.
While stream-based sockets can be handled using using L<IO::Async::Stream>,
datagram or raw sockets do not provide a bytestream. For these, the
local/lib/perl5/IO/Async.pm view on Meta::CPAN
from its initial start time. It is reliable and will not drift due to the time
taken to run the callback.
The L<IO::Async::Loop> also supports methods for managing timed events on a
lower level. Events may be absolute, or relative in time to the time they are
installed.
=head2 Signals
An L<IO::Async::Signal> object represents a POSIX signal, which will invoke a
callback when the given signal is received by the process. Multiple objects
watching the same signal can be used; they will all invoke in no particular
order.
=head2 Processes Management
An L<IO::Async::PID> object invokes its event when a given child process
exits. An L<IO::Async::Process> object can start a new child process running
either a given block of code, or executing a given command, set up pipes on
its filehandles, write to or read from these pipes, and invoke its event when
the child process exits.
=head2 Loops
The L<IO::Async::Loop> object class represents an abstract collection of
L<IO::Async::Notifier> objects, and manages the actual filehandle IO
watchers, timers, signal handlers, and other functionality. It performs all
of the abstract collection management tasks, and leaves the actual OS
interactions to a particular subclass for the purpose.
L<IO::Async::Loop::Poll> uses an L<IO::Poll> object for this test.
local/lib/perl5/IO/Async.pm view on Meta::CPAN
Other subclasses of loop may appear on CPAN under their own dists; see the
L</SEE ALSO> section below for more detail.
As well as these general-purpose classes, the L<IO::Async::Loop> constructor
also supports looking for OS-specific subclasses, in case a more efficient
implementation exists for the specific OS it runs on.
=head2 Child Processes
The L<IO::Async::Loop> object provides a number of methods to facilitate the
running of child processes. C<spawn_child> is primarily a wrapper around the
typical C<fork(2)>/C<exec(2)> style of starting child processes, and
C<run_child> provide a method similar to perl's C<readpipe> (which is used
to implement backticks C<``>).
=head2 File Change Watches
The L<IO::Async::File> object observes changes to C<stat(2)> properties of a
file, directory, or other filesystem object. It invokes callbacks when
properties change. This is used by L<IO::Async::FileStream> which presents
the same events as a L<IO::Async::Stream> but operates on a regular file on
the filesystem, observing it for updates.
=head2 Asynchronous Co-routines and Functions
The C<IO::Async> framework generally provides mechanisms for multiplexing IO
tasks between different handles, so there aren't many occasions when it is
necessary to run code in another thread or process. Two cases where this does
become useful are when:
=over 4
=item *
A large amount of computationally-intensive work needs to be performed.
=item *
An OS or library-level function needs to be called, that will block, and
no asynchronous version is supplied.
=back
For these cases, an instance of L<IO::Async::Function> can be used around
a code block, to execute it in a worker child process or set of processes.
The code in the sub-process runs isolated from the main program, communicating
only by function call arguments and return values. This can be used to solve
problems involving state-less library functions.
An L<IO::Async::Routine> object wraps a code block running in a separate
process to form a kind of co-routine. Communication with it happens via
L<IO::Async::Channel> objects. It can be used to solve any sort of problem
involving keeping a possibly-stateful co-routine running alongside the rest of
an asynchronous program.
=head2 Futures
An L<IO::Async::Future> object represents a single outstanding action that is
yet to complete, such as a name resolution operation or a socket connection.
It stands in contrast to a L<IO::Async::Notifier>, which is an object that
represents an ongoing source of activity, such as a readable filehandle of
local/lib/perl5/IO/Async/Channel.pm view on Meta::CPAN
C<IO::Async::Channel> - pass values into or out from an L<IO::Async::Routine>
=head1 DESCRIPTION
A C<IO::Async::Channel> object allows Perl values to be passed into or out of
an L<IO::Async::Routine>. It is intended to be used primarily with a Routine
object rather than independently. For more detail and examples on how to use
this object see also the documentation for L<IO::Async::Routine>.
A Channel object is shared between the main process of the program and the
process running within the Routine. In the main process it will be used in
asynchronous mode, and in the Routine process it will be used in synchronous
mode. In asynchronous mode all methods return immediately and use
L<IO::Async>-style futures or callback functions. In synchronous within the
Routine process the methods block until they are ready and may be used for
flow-control within the routine. Alternatively, a Channel may be shared
between two different Routine objects, and not used directly by the
controlling program.
The channel itself represents a FIFO of Perl reference values. New values may
be put into the channel by the C<send> method in either mode. Values may be
retrieved from it by the C<recv> method. Values inserted into the Channel are
snapshot by the C<send> method. Any changes to referred variables will not be
observed by the other end of the Channel after the C<send> method returns.
local/lib/perl5/IO/Async/Channel.pm view on Meta::CPAN
=head1 CONSTRUCTOR
=cut
=head2 new
$channel = IO::Async::Channel->new
Returns a new C<IO::Async::Channel> object. This object reference itself
should be shared by both sides of a C<fork()>ed process. After C<fork()> the
two C<setup_*> methods may be used to configure the object for operation on
either end.
While this object does in fact inherit from L<IO::Async::Notifier>, it should
not be added to a Loop object directly; event management will be handled by
its containing L<IO::Async::Routine> object.
=cut
=head1 METHODS
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
use Carp;
use Scalar::Util qw( weaken );
use POSIX qw( _exit dup dup2 nice );
use constant LENGTH_OF_I => length( pack( "I", 0 ) );
=head1 NAME
C<IO::Async::ChildManager> - facilitates the execution of child processes
=head1 SYNOPSIS
This object is used indirectly via an L<IO::Async::Loop>:
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
...
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
on_exit => sub {
my ( $pid, $exitcode ) = @_;
my $status = ( $exitcode >> 8 );
print "Command exited with status $status\n";
},
);
$loop->spawn_child(
code => sub {
do_something; # executes in a child process
return 1;
},
on_exit => sub {
my ( $pid, $exitcode, $dollarbang, $dollarat ) = @_;
my $status = ( $exitcode >> 8 );
print "Child process exited with status $status\n";
print " OS error was $dollarbang, exception was $dollarat\n";
},
);
=head1 DESCRIPTION
This module extends the functionality of the containing L<IO::Async::Loop> to
manage the execution of child processes. It acts as a central point to store
PID values of currently-running children, and to call the appropriate
continuation handler code when the process terminates. It provides useful
wrapper methods that set up filehandles and other child process details, and
to capture the child process's STDOUT and STDERR streams.
=cut
# Writing to variables of $> and $) have tricky ways to obtain error results
sub setuid
{
my ( $uid ) = @_;
$> = $uid; my $saved_errno = $!;
$> == $uid and return 1;
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
When active, the following methods are available on the containing C<Loop>
object.
=cut
=head2 spawn_child
$pid = $loop->spawn_child( %params )
This method creates a new child process to run a given code block or command.
The C<%params> hash takes the following keys:
=over 8
=item command => ARRAY or STRING
Either a reference to an array containing the command and its arguments, or a
plain string containing the command. This value is passed into perl's
C<exec> function.
=item code => CODE
A block of code to execute in the child process. It will be called in scalar
context inside an C<eval> block.
=item setup => ARRAY
A reference to an array which gives file descriptors to set up in the child
process before running the code or command. See below.
=item on_exit => CODE
A continuation to be called when the child processes exits. It will be invoked
in the following way:
$on_exit->( $pid, $exitcode, $dollarbang, $dollarat )
The second argument is passed the plain perl C<$?> value.
=back
Exactly one of the C<command> or C<code> keys must be specified.
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
);
# Parent
close( $writepipe );
return $self->_spawn_in_parent( $readpipe, $kid, $on_exit );
}
=head2 C<setup> array
This array gives a list of file descriptor operations to perform in the child
process after it has been C<fork(2)>ed from the parent, before running the code
or command. It consists of name/value pairs which are ordered; the operations
are performed in the order given.
=over 8
=item fdI<n> => ARRAY
Gives an operation on file descriptor I<n>. The first element of the array
defines the operation to be performed:
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
=item stdin => ...
=item stdout => ...
=item stderr => ...
Shortcuts for C<fd0>, C<fd1> and C<fd2> respectively.
=item env => HASH
A reference to a hash to set as the child process's environment.
Note that this will entirely set a new environment, completely replacing the
existing one. If you want to simply add new keys or change the values of some
keys without removing the other existing ones, you can simply copy C<%ENV>
into the hash before setting new keys:
env => {
%ENV,
ANOTHER => "key here",
}
=item nice => INT
Change the child process's scheduling priority using C<POSIX::nice>.
=item chdir => STRING
Change the child process's working directory using C<chdir>.
=item setuid => INT
=item setgid => INT
Change the child process's effective UID or GID.
=item setgroups => ARRAY
Change the child process's groups list, to those groups whose numbers are
given in the ARRAY reference.
On most systems, only the privileged superuser change user or group IDs.
L<IO::Async> will B<NOT> check before detaching the child process whether
this is the case.
If setting both the primary GID and the supplementary groups list, it is
suggested to set the primary GID first. Moreover, some operating systems may
require that the supplementary groups list contains the primary GID.
=back
If no directions for what to do with C<stdin>, C<stdout> and C<stderr> are
given, a default of C<keep> is implied. All other file descriptors will be
local/lib/perl5/IO/Async/FileStream.pm view on Meta::CPAN
},
);
$loop->add( $filestream );
$loop->run;
=head1 DESCRIPTION
This subclass of L<IO::Async::Stream> allows reading the end of a regular file
which is being appended to by some other process. It invokes the C<on_read>
event when more data has been added to the file.
This class provides an API identical to L<IO::Async::Stream> when given a
C<read_handle>; it should be treated similarly. In particular, it can be given
an C<on_read> handler, or subclassed to provide an C<on_read> method, or even
used as the C<transport> for an L<IO::Async::Protocol::Stream> object.
It will not support writing.
To watch a file, directory, or other filesystem entity for updates of other
local/lib/perl5/IO/Async/FileStream.pm view on Meta::CPAN
default value of 4 times the blocksize if not defined.
To force it to always search through the entire file contents, set this
explicitly to C<0>.
=back
Because regular file reading happens synchronously, this entire method
operates entirely synchronously. If the file is very large, it may take a
while to read back through the entire contents. While this is happening no
other events can be invoked in the process.
When looking for a string or regexp match, this method appends the
previously-read buffer to each block read from the file, in case a match
becomes split across two reads. If C<blocksize> is reduced to a very small
value, take care to ensure it isn't so small that a match may not be noticed.
This is most likely useful for seeking after the last complete line in a
line-based log file, to commence reading from the end, while still managing to
capture any partial content that isn't yet a complete line.
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
)->on_done( sub {
my $isprime = shift;
print "123454321 " . ( $isprime ? "is" : "is not" ) . " a prime number\n";
})->on_fail( sub {
print STDERR "Cannot determine if it's prime - $_[0]\n";
})->get;
=head1 DESCRIPTION
This subclass of L<IO::Async::Notifier> wraps a function body in a collection
of worker processes, to allow it to execute independently of the main process.
The object acts as a proxy to the function, allowing invocations to be made by
passing in arguments, and invoking a continuation in the main process when the
function returns.
The object represents the function code itself, rather than one specific
invocation of it. It can be called multiple times, by the C<call> method.
Multiple outstanding invocations can be called; they will be dispatched in
the order they were queued. If only one worker process is used then results
will be returned in the order they were called. If multiple are used, then
each request will be sent in the order called, but timing differences between
each worker may mean results are returned in a different order.
Since the code block will be called multiple times within the same child
process, it must take care not to modify any of its state that might affect
subsequent calls. Since it executes in a child process, it cannot make any
modifications to the state of the parent program. Therefore, all the data
required to perform its task must be represented in the call arguments, and
all of the result must be represented in the return values.
The Function object is implemented using an L<IO::Async::Routine> with two
L<IO::Async::Channel> objects to pass calls into and results out from it.
The L<IO::Async> framework generally provides mechanisms for multiplexing IO
tasks between different handles, so there aren't many occasions when such an
asynchronous function is necessary. Two cases where this does become useful
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
=item 2.
When a blocking OS syscall or library-level function needs to be called, and
no nonblocking or asynchronous version is supplied. This is used by
L<IO::Async::Resolver>.
=back
This object is ideal for representing "pure" functions; that is, blocks of
code which have no stateful effect on the process, and whose result depends
only on the arguments passed in. For a more general co-routine ability, see
also L<IO::Async::Routine>.
=cut
=head1 PARAMETERS
The following named parameters may be passed to C<new> or C<configure>:
=head2 code => CODE
The body of the function to execute.
@result = $code->( @args )
=head2 init_code => CODE
Optional. If defined, this is invoked exactly once in every child process or
thread, after it is created, but before the first invocation of the function
body itself.
$init_code->()
=head2 model => "fork" | "thread"
Optional. Requests a specific L<IO::Async::Routine> model. If not supplied,
leaves the default choice up to Routine.
=head2 min_workers => INT
=head2 max_workers => INT
The lower and upper bounds of worker processes to try to keep running. The
actual number running at any time will be kept somewhere between these bounds
according to load.
=head2 max_worker_calls => INT
Optional. If provided, stop a worker process after it has processed this
number of calls. (New workers may be started to replace stopped ones, within
the bounds given above).
=head2 idle_timeout => NUM
Optional. If provided, idle worker processes will be shut down after this
amount of time, if there are more than C<min_workers> of them.
=head2 exit_on_die => BOOL
Optional boolean, controls what happens after the C<code> throws an
exception. If missing or false, the worker will continue running to process
more requests. If true, the worker will be shut down. A new worker might be
constructed by the C<call> method to replace it, if necessary.
=head2 setup => ARRAY
Optional array reference. Specifies the C<setup> key to pass to the underlying
L<IO::Async::Process> when setting up new worker processes.
=cut
sub _init
{
my $self = shift;
$self->SUPER::_init( @_ );
$self->{min_workers} = 1;
$self->{max_workers} = 8;
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
The following methods documented with a trailing call to C<< ->get >> return
L<Future> instances.
=cut
=head2 start
$function->start
Start the worker processes
=cut
sub start
{
my $self = shift;
$self->_new_worker for 1 .. $self->{min_workers};
}
=head2 stop
$function->stop
Stop the worker processes
=cut
sub stop
{
my $self = shift;
$self->{stopping} = 1;
foreach my $worker ( $self->_worker_objects ) {
$worker->stop;
}
}
=head2 restar
$function->restart
Gracefully stop and restart all the worker processes.
=cut
sub restart
{
my $self = shift;
$self->stop;
$self->start;
}
=head2 call
@result = $function->call( %params )->get
Schedules an invocation of the contained function to be executed on one of the
worker processes. If a non-busy worker is available now, it will be called
immediately. If not, it will be queued and sent to the next free worker that
becomes available.
The request will already have been serialised by the marshaller, so it will be
safe to modify any referenced data structures in the arguments after this call
returns.
The C<%params> hash takes the following keys:
=over 8
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
=over 8
=item on_result => CODE
A continuation that is invoked when the code has been executed. If the code
returned normally, it is called as:
$on_result->( 'return', @values )
If the code threw an exception, or some other error occured such as a closed
connection or the process died, it is called as:
$on_result->( 'error', $exception_name )
=item on_return => CODE and on_error => CODE
An alternative to C<on_result>. Two continuations to use in either of the
circumstances given above. They will be called directly, without the leading
'return' or 'error' value.
=back
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
sub _worker_objects
{
my $self = shift;
return values %{ $self->{workers} };
}
=head2 workers
$count = $function->workers
Returns the total number of worker processes available
=cut
sub workers
{
my $self = shift;
return scalar keys %{ $self->{workers} };
}
=head2 workers_busy
$count = $function->workers_busy
Returns the number of worker processes that are currently busy
=cut
sub workers_busy
{
my $self = shift;
return scalar grep { $_->{busy} } $self->_worker_objects;
}
=head2 workers_idle
$count = $function->workers_idle
Returns the number of worker processes that are currently idle
=cut
sub workers_idle
{
my $self = shift;
return scalar grep { !$_->{busy} } $self->_worker_objects;
}
sub _new_worker
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
$loop->run;
=head1 DESCRIPTION
This module provides an abstract class which implements the core loop of the
L<IO::Async> framework. Its primary purpose is to store a set of
L<IO::Async::Notifier> objects or subclasses of them. It handles all of the
lower-level set manipulation actions, and leaves the actual IO readiness
testing/notification to the concrete class that implements it. It also
provides other functionality such as signal handling, child process managing,
and timers.
See also the two bundled Loop subclasses:
=over 4
=item L<IO::Async::Loop::Select>
=item L<IO::Async::Loop::Poll>
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
my $self = shift;
$self->stop;
}
=head2 post_fork
$loop->post_fork
The base implementation of this method does nothing. It is provided in case
some Loop subclasses should take special measures after a C<fork()> system
call if the main body of the program should survive in both running processes.
This may be required, for example, in a long-running server daemon that forks
multiple copies on startup after opening initial listening sockets. A loop
implementation that uses some in-kernel resource that becomes shared after
forking (for example, a Linux C<epoll> or a BSD C<kqueue> filehandle) would
need recreating in the new child process before the program can continue.
=cut
sub post_fork
{
# empty
}
###########
# Futures #
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
The name of the signal to attach to. This should be a bare name like C<TERM>.
=item $code
A CODE reference to the handling callback.
=back
Attaching to C<SIGCHLD> is not recommended because of the way all child
processes use it to report their termination. Instead, the C<watch_child>
method should be used to watch for termination of a given child process. A
warning will be printed if C<SIGCHLD> is passed here, but in future versions
of L<IO::Async> this behaviour may be disallowed altogether.
See also L<POSIX> for the C<SIGI<name>> constants.
For a more flexible way to use signals from within Notifiers, see instead the
L<IO::Async::Signal> object.
=cut
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=head2 later
$loop->later( $code )
Schedules a code reference to be invoked as soon as the current round of IO
operations is complete.
The code reference is never invoked immediately, though the loop will not
perform any blocking operations between when it is installed and when it is
invoked. It may call C<select>, C<poll> or equivalent with a zero-second
timeout, and process any currently-pending IO conditions before the code is
invoked, but it will not block for a non-zero amount of time.
This method is implemented using the C<watch_idle> method, with the C<when>
parameter set to C<later>. It will return an ID value that can be passed to
C<unwatch_idle> if required.
=cut
sub later
{
my $self = shift;
my ( $code ) = @_;
return $self->watch_idle( when => 'later', code => $code );
}
=head2 spawn_child
$loop->spawn_child( %params )
This method creates a new child process to run a given code block or command.
For more detail, see the C<spawn_child> method on the
L<IO::Async::ChildManager> class.
=cut
sub spawn_child
{
my $self = shift;
my %params = @_;
my $childmanager = $self->{childmanager} ||=
$self->__new_feature( "IO::Async::ChildManager" );
$childmanager->spawn_child( %params );
}
=head2 open_child
$pid = $loop->open_child( %params )
This creates a new child process to run the given code block or command, and
attaches filehandles to it that the parent will watch. This method is a light
wrapper around constructing a new L<IO::Async::Process> object, provided
largely for backward compatibility. New code ought to construct such an object
directly, as it may provide more features than are available here.
The C<%params> hash takes the following keys:
=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> 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
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
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
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=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
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
$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
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
sub time
{
my $self = shift;
return Time::HiRes::time;
}
=head2 fork
$pid = $loop->fork( %params )
This method creates a new child process to run a given code block, returning
its process ID.
=over 8
=item code => CODE
A block of code to execute in the child process. It will be called in scalar
context inside an C<eval> block. The return value will be used as the
C<exit(2)> code from the child if it returns (or 255 if it returned C<undef> or
thows an exception).
=item on_exit => CODE
A optional continuation to be called when the child processes exits. It will
be invoked in the following way:
$on_exit->( $pid, $exitcode )
The second argument is passed the plain perl C<$?> value.
This key is optional; if not supplied, the calling code should install a
handler using the C<watch_child> method.
=item keep_signals => BOOL
Optional boolean. If missing or false, any CODE references in the C<%SIG> hash
will be removed and restored back to C<DEFAULT> in the child process. If true,
no adjustment of the C<%SIG> hash will be performed.
=back
=cut
sub fork
{
my $self = shift;
my %params = @_;
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=back
The C<when> parameter defines the time at which the callback will later be
invoked. Must be one of the following values:
=over 8
=item later
Callback is invoked after the current round of IO events have been processed
by the loop's underlying C<loop_once> method.
If a new idle watch is installed from within a C<later> callback, the
installed one will not be invoked during this round. It will be deferred for
the next time C<loop_once> is called, after any IO events have been handled.
=back
If there are pending idle handlers, then the C<loop_once> method will use a
zero timeout; it will return immediately, having processed any IO events and
idle handlers.
The returned C<$id> value can be used to identify the idle handler in case it
needs to be removed, by calling the C<unwatch_idle> method. Note this value
may be a reference, so if it is stored it should be released after the
callback has been invoked or cancled, so the referrant itself can be freed.
This and C<unwatch_idle> are optional; a subclass may implement neither, or
both. If it implements neither then idle handling will be performed by the
base class, using the C<_adjust_timeout> and C<_manage_queues> methods.
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
$childwatches->{0}->( $zid, $status );
# Don't delete it
}
}
}
=head2 watch_child
$loop->watch_child( $pid, $code )
This method adds a new handler for the termination of the given child process
PID, or all child processes.
=over 8
=item $pid
The PID to watch. Will report on all child processes if this is 0.
=item $code
A CODE reference to the exit handler. It will be invoked as
$code->( $pid, $? )
The second argument is passed the plain perl C<$?> value.
=back
After invocation, the handler for a PID-specific watch is automatically
removed. The all-child watch will remain until it is removed by
C<unwatch_child>.
This and C<unwatch_child> are optional; a subclass may implement neither, or
both. If it implements neither then child watching will be performed by using
C<watch_signal> to install a C<SIGCHLD> handler, which will use C<waitpid> to
look for exited child processes.
If both a PID-specific and an all-process watch are installed, there is no
ordering guarantee as to which will be called first.
=cut
sub watch_child
{
my $self = shift;
my ( $pid, $code ) = @_;
my $childwatches = $self->{childwatches};
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
}
}
$childwatches->{$pid} = $code;
}
=head2 unwatch_child
$loop->unwatch_child( $pid )
This method removes a watch on an existing child process PID.
=cut
sub unwatch_child
{
my $self = shift;
my ( $pid ) = @_;
my $childwatches = $self->{childwatches};
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=item IO_ASYNC_WATCHDOG_INTERVAL => INT
Watchdog interval, in seconds, to pass to the C<alarm(2)> call. Defaults to 10
seconds.
=item IO_ASYNC_WATCHDOG_SIGABRT => BOOL
If enabled, the watchdog signal handler will raise a C<SIGABRT>, which usually
has the effect of breaking out of a running program in debuggers such as
F<gdb>. If not set then the process is terminated by throwing an exception with
C<die>.
=back
=cut
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
local/lib/perl5/IO/Async/Loop/Select.pm view on Meta::CPAN
$self->_manage_queues;
alarm( 0 ) if WATCHDOG_ENABLE;
}
=head2 loop_once
$count = $loop->loop_once( $timeout )
This method calls the C<pre_select> method to prepare the bitvectors for a
C<select> syscall, performs it, then calls C<post_select> to process the
result. It returns the total number of callbacks invoked by the
C<post_select> method, or C<undef> if the underlying C<select(2)> syscall
returned an error.
=cut
sub loop_once
{
my $self = shift;
my ( $timeout ) = @_;
local/lib/perl5/IO/Async/LoopTests.pm view on Meta::CPAN
$loop->later( sub { $called = 4 } );
$loop->loop_once( 1 );
is( $called, 4, '$loop->later shortcut works' );
}
=head2 child
Tests the Loop's support for watching child processes by PID
=cut
sub run_in_child(&)
{
my $kid = fork;
defined $kid or die "Cannot fork() - $!";
return $kid if $kid;
shift->();
local/lib/perl5/IO/Async/LoopTests.pm view on Meta::CPAN
undef $exitcode;
wait_for { defined $exitcode };
ok( ($exitcode & 0x7f) == 0, 'WIFEXITED($exitcode) after child exit' );
is( ($exitcode >> 8), 3, 'WEXITSTATUS($exitcode) after child exit' );
SKIP: {
skip "This OS does not have signals", 1 unless IO::Async::OS->HAVE_SIGNALS;
# We require that SIGTERM perform its default action; i.e. terminate the
# process. Ensure this definitely happens, in case the test harness has it
# ignored or handled elsewhere.
local $SIG{TERM} = "DEFAULT";
$kid = run_in_child {
sleep( 10 );
# Just in case the parent died already and didn't kill us
exit( 0 );
};
$loop->watch_child( $kid => sub { ( undef, $exitcode ) = @_; } );
local/lib/perl5/IO/Async/LoopTests.pm view on Meta::CPAN
is( ($exitcode & 0x7f), SIGTERM, 'WTERMSIG($exitcode) after SIGTERM' );
}
my %kids;
$loop->watch_child( 0 => sub { my ( $kid ) = @_; delete $kids{$kid} } );
%kids = map { run_in_child { exit 0 } => 1 } 1 .. 3;
is( scalar keys %kids, 3, 'Waiting for 3 child processes' );
wait_for { !keys %kids };
ok( !keys %kids, 'All child processes reclaimed' );
}
=head2 control
Tests that the C<run>, C<stop>, C<loop_once> and C<loop_forever> methods
behave correctly
=cut
use constant count_tests_control => 8;
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
=item *
L<IO::Async::Timer> - base class for Notifiers that use timed delays
=item *
L<IO::Async::Signal> - event callback on receipt of a POSIX signal
=item *
L<IO::Async::PID> - event callback on exit of a child process
=item *
L<IO::Async::Process> - start and manage a child process
=back
For more detail, see the SYNOPSIS section in one of the above.
One case where this object class would be used, is when a library wishes to
provide a sub-component which consists of multiple other C<Notifier>
subclasses, such as C<Handle>s and C<Timers>, but no particular object is
suitable to be the root of a tree. In this case, a plain C<Notifier> object
can be used as the tree root, and all the other notifiers added as children of
local/lib/perl5/IO/Async/OS.pm view on Meta::CPAN
# Can we rename() files that are open?
use constant HAVE_RENAME_OPEN_FILES => 1;
# Do we have IO::Socket::IP available?
use constant HAVE_IO_SOCKET_IP => defined eval { require IO::Socket::IP };
# Can we reliably watch for POSIX signals, including SIGCHLD to reliably
# inform us that a fork()ed child has exit()ed?
use constant HAVE_SIGNALS => 1;
# Do we support POSIX-style true fork()ed processes at all?
use constant HAVE_POSIX_FORK => !$ENV{IO_ASYNC_NO_FORK};
# Can we potentially support threads? (would still need to 'require threads')
use constant HAVE_THREADS => !$ENV{IO_ASYNC_NO_THREADS} &&
eval { require Config && $Config::Config{useithreads} };
# Preferred trial order for built-in Loop classes
use constant LOOP_BUILTIN_CLASSES => qw( Poll Select );
# Should there be any other Loop classes we try before the builtin ones?
use constant LOOP_PREFER_CLASSES => ();
local/lib/perl5/IO/Async/OS.pm view on Meta::CPAN
with names beginning C<HAVE_> which describe various features that may or may
not be available on the OS or perl build. Most of these are either hard-coded
per OS, or detected at runtime.
The following constants may be overridden by environment variables.
=over 4
=item * HAVE_POSIX_FORK
True if the C<fork()> call has full POSIX semantics (full process separation).
This is true on most OSes but false on MSWin32.
This may be overridden to be false by setting the environment variable
C<IO_ASYNC_NO_FORK>.
=item * HAVE_THREADS
True if C<ithreads> are available, meaning that the C<threads> module can be
used. This depends on whether perl was built with threading support.
local/lib/perl5/IO/Async/OS.pm view on Meta::CPAN
pipe( my ( $rd, $wr ) ) or return;
return ( $rd, $wr );
}
=head2 pipequad
( $rdA, $wrA, $rdB, $wrB ) = IO::Async::OS->pipequad
This method is intended for creating two pairs of filehandles that are linked
together, suitable for passing as the STDIN/STDOUT pair to a child process.
After this function returns, C<$rdA> and C<$wrA> will be a linked pair, as
will C<$rdB> and C<$wrB>.
On platforms that support C<socketpair(2)>, this implementation will be
preferred, in which case C<$rdA> and C<$wrB> will actually be the same
filehandle, as will C<$rdB> and C<$wrA>. This saves a file descriptor in the
parent process.
When creating a L<IO::Async::Stream> or subclass of it, the C<read_handle>
and C<write_handle> parameters should always be used.
my ( $childRd, $myWr, $myRd, $childWr ) = IO::Async::OS->pipequad;
IO::Async::OS->open_child(
stdin => $childRd,
stdout => $childWr,
...
local/lib/perl5/IO/Async/OS/linux.pm view on Meta::CPAN
This module contains OS support code for C<Linux>.
See instead L<IO::Async::OS>.
=cut
# Suggest either Epoll or Ppoll loops first if they are installed
use constant LOOP_PREFER_CLASSES => qw( Epoll Ppoll );
# Try to use /proc/pid/fd to get the list of actually-open file descriptors
# for our process. Saves a bit of time when running with high ulimit -n /
# fileno counts.
sub potentially_open_fds
{
my $class = shift;
opendir my $fd_path, "/proc/$$/fd" or do {
warn "Cannot open /proc/$$/fd, falling back to generic method - $!";
return $class->SUPER::potentially_open_fds
};
local/lib/perl5/IO/Async/PID.pm view on Meta::CPAN
use strict;
use warnings;
use base qw( IO::Async::Notifier );
our $VERSION = '0.70';
use Carp;
=head1 NAME
C<IO::Async::PID> - event callback on exit of a child process
=head1 SYNOPSIS
use IO::Async::PID;
use POSIX qw( WEXITSTATUS );
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
my $kid = $loop->fork(
code => sub {
print "Child sleeping..\n";
sleep 10;
print "Child exiting\n";
return 20;
},
);
print "Child process $kid started\n";
my $pid = IO::Async::PID->new(
pid => $kid,
on_exit => sub {
my ( $self, $exitcode ) = @_;
printf "Child process %d exited with status %d\n",
$self->pid, WEXITSTATUS($exitcode);
},
);
$loop->add( $pid );
$loop->run;
=head1 DESCRIPTION
This subclass of L<IO::Async::Notifier> invokes its callback when a process
exits.
For most use cases, a L<IO::Async::Process> object provides more control of
setting up the process, connecting filehandles to it, sending data to and
receiving data from it.
=cut
=head1 EVENTS
The following events are invoked, either using subclass methods or CODE
references in parameters:
=head2 on_exit $exitcode
Invoked when the watched process exits.
=cut
=head1 PARAMETERS
The following named parameters may be passed to C<new> or C<configure>:
=head2 pid => INT
The process ID to watch. Must be given before the object has been added to the
containing L<IO::Async::Loop> object.
=head2 on_exit => CODE
CODE reference for the C<on_exit> event.
Once the C<on_exit> continuation has been invoked, the C<IO::Async::PID>
object is removed from the containing L<IO::Async::Loop> object.
=cut
local/lib/perl5/IO/Async/PID.pm view on Meta::CPAN
return $self->{pid};
}
=head1 METHODS
=cut
=head2 pid
$process_id = $pid->pid
Returns the underlying process ID
=cut
sub pid
{
my $self = shift;
return $self->{pid};
}
=head2 kill
$pid->kill( $signal )
Sends a signal to the process
=cut
sub kill
{
my $self = shift;
my ( $signal ) = @_;
kill $signal, $self->pid or croak "Cannot kill() - $!";
}
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
use Carp;
use Socket qw( SOCK_STREAM );
use Future;
use IO::Async::OS;
=head1 NAME
C<IO::Async::Process> - start and manage a child process
=head1 SYNOPSIS
use IO::Async::Process;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
my $process = IO::Async::Process->new(
command => [ "tr", "a-z", "n-za-m" ],
stdin => {
from => "hello world\n",
},
stdout => {
on_read => sub {
my ( $stream, $buffref ) = @_;
while( $$buffref =~ s/^(.*)\n// ) {
print "Rot13 of 'hello world' is '$1'\n";
}
return 0;
},
},
on_finish => sub {
$loop->stop;
},
);
$loop->add( $process );
$loop->run;
=head1 DESCRIPTION
This subclass of L<IO::Async::Notifier> starts a child process, and invokes a
callback when it exits. The child process can either execute a given block of
code (via C<fork(2)>), or a command.
=cut
=head1 EVENTS
The following events are invoked, either using subclass methods or CODE
references in parameters:
=head2 on_finish $exitcode
Invoked after the process has exited by normal means (i.e. an C<exit(2)>
syscall from a process, or C<return>ing from the code block), and has closed
all its file descriptors.
=head2 on_exception $exception, $errno, $exitcode
Invoked when the process exits by an exception from C<code>, or by failing to
C<exec(2)> the given command. C<$errno> will be a dualvar, containing both
number and string values. After a successful C<exec()> call, this condition
can no longer happen.
Note that this has a different name and a different argument order from
C<< Loop->open_child >>'s C<on_error>.
If this is not provided and the process exits with an exception, then
C<on_finish> is invoked instead, being passed just the exit code.
Since this is just the results of the underlying C<< $loop->spawn_child >>
C<on_exit> handler in a different order it is possible that the C<$exception>
field will be an empty string. It will however always be defined. This can be
used to distinguish the two cases:
on_exception => sub {
my ( $self, $exception, $errno, $exitcode ) = @_;
if( length $exception ) {
print STDERR "The process died with the exception $exception " .
"(errno was $errno)\n";
}
elsif( ( my $status = W_EXITSTATUS($exitcode) ) == 255 ) {
print STDERR "The process failed to exec() - $errno\n";
}
else {
print STDERR "The process exited with exit status $status\n";
}
}
=cut
=head1 CONSTRUCTOR
=cut
=head2 new
$process = IO::Async::Process->new( %args )
Constructs a new C<IO::Async::Process> object and returns it.
Once constructed, the C<Process> will need to be added to the C<Loop> before
the child process is started.
=cut
sub _init
{
my $self = shift;
$self->SUPER::_init( @_ );
$self->{to_close} = {};
$self->{finish_futures} = [];
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
=head2 on_finish => CODE
=head2 on_exception => CODE
CODE reference for the event handlers.
Once the C<on_finish> continuation has been invoked, the C<IO::Async::Process>
object is removed from the containing L<IO::Async::Loop> object.
The following parameters may be passed to C<new>, or to C<configure> before
the process has been started (i.e. before it has been added to the C<Loop>).
Once the process is running these cannot be changed.
=head2 command => ARRAY or STRING
Either a reference to an array containing the command and its arguments, or a
plain string containing the command. This value is passed into perl's
C<exec(2)> function.
=head2 code => CODE
A block of code to execute in the child process. It will be called in scalar
context inside an C<eval> block.
=head2 setup => ARRAY
Optional reference to an array to pass to the underlying C<Loop>
C<spawn_child> method.
=head2 fdI<n> => HASH
A hash describing how to set up file descriptor I<n>. The hash may contain the
following keys:
=over 4
=item via => STRING
Configures how this file descriptor will be configured for the child process.
Must be given one of the following mode names:
=over 4
=item pipe_read
The child will be given the writing end of a C<pipe(2)>; the parent may read
from the other.
=item pipe_write
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
The value of this argument is implied by any of the following alternatives.
=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 into => SCALAR
The child will be given the writing end of a pipe. The referenced scalar will
be filled by data read from the child process. This data may not be available
until the pipe has been closed by the child.
=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
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
sub configure
{
my $self = shift;
my %params = @_;
foreach (qw( on_finish on_exception )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
}
# All these parameters can only be configured while the process isn't
# running
my %setup_params;
foreach (qw( code command setup stdin stdout stderr stdio ), grep { m/^fd\d+$/ } keys %params ) {
$setup_params{$_} = delete $params{$_} if exists $params{$_};
}
if( $self->is_running ) {
keys %setup_params and croak "Cannot configure a running Process with " . join ", ", keys %setup_params;
}
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
return "[$pid]" unless $self->is_running;
return "$pid";
}
=head1 METHODS
=cut
=head2 pid
$pid = $process->pid
Returns the process ID of the process, if it has been started, or C<undef> if
not. Its value is preserved after the process exits, so it may be inspected
during the C<on_finish> or C<on_exception> events.
=cut
sub pid
{
my $self = shift;
return $self->{pid};
}
=head2 kill
$process->kill( $signal )
Sends a signal to the process
=cut
sub kill
{
my $self = shift;
my ( $signal ) = @_;
kill $signal, $self->pid or croak "Cannot kill() - $!";
}
=head2 is_running
$running = $process->is_running
Returns true if the Process has been started, and has not yet finished.
=cut
sub is_running
{
my $self = shift;
return $self->{running};
}
=head2 is_exited
$exited = $process->is_exited
Returns true if the Process has finished running, and finished due to normal
C<exit(2)>.
=cut
sub is_exited
{
my $self = shift;
return defined $self->{exitcode} ? ( $self->{exitcode} & 0x7f ) == 0 : undef;
}
=head2 exitstatus
$status = $process->exitstatus
If the process exited due to normal C<exit(2)>, returns the value that was
passed to C<exit(2)>. Otherwise, returns C<undef>.
=cut
sub exitstatus
{
my $self = shift;
return defined $self->{exitcode} ? ( $self->{exitcode} >> 8 ) : undef;
}
=head2 exception
$exception = $process->exception
If the process exited due to an exception, returns the exception that was
thrown. Otherwise, returns C<undef>.
=cut
sub exception
{
my $self = shift;
return $self->{dollarat};
}
=head2 errno
$errno = $process->errno
If the process exited due to an exception, returns the numerical value of
C<$!> at the time the exception was thrown. Otherwise, returns C<undef>.
=cut
sub errno
{
my $self = shift;
return $self->{dollarbang}+0;
}
=head2 errstr
$errstr = $process->errstr
If the process exited due to an exception, returns the string value of
C<$!> at the time the exception was thrown. Otherwise, returns C<undef>.
=cut
sub errstr
{
my $self = shift;
return $self->{dollarbang}."";
}
=head2 fd
$stream = $process->fd( $fd )
Returns the L<IO::Async::Stream> or L<IO::Async::Socket> associated with the
given FD number. This must have been set up by a C<configure> argument prior
to adding the C<Process> object to the C<Loop>.
The returned object have its read or write handle set to the other end of a
pipe or socket connected to that FD number in the child process. Typically,
this will be used to call the C<write> method on, to write more data into the
child, or to set an C<on_read> handler to read data out of the child.
The C<on_closed> event for these streams must not be changed, or it will break
the close detection used by the C<Process> object and the C<on_finish> event
will not be invoked.
=cut
sub fd
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
}
=head2 stdin
=head2 stdout
=head2 stderr
=head2 stdio
$stream = $process->stdin
$stream = $process->stdout
$stream = $process->stderr
$stream = $process->stdio
Shortcuts for calling C<fd> with 0, 1, 2 or C<io> respectively, to obtain the
L<IO::Async::Stream> representing the standard input, output, error, or
combined input/output streams of the child process.
=cut
sub stdin { shift->fd( 0 ) }
sub stdout { shift->fd( 1 ) }
sub stderr { shift->fd( 2 ) }
sub stdio { shift->fd( 'io' ) }
=head1 EXAMPLES
=head2 Capturing the STDOUT stream of a process
By configuring the C<stdout> filehandle of the process using the C<into> key,
data written by the process can be captured.
my $stdout;
my $process = IO::Async::Process->new(
command => [ "writing-program", "arguments" ],
stdout => { into => \$stdout },
on_finish => sub {
print "The process has finished, and wrote:\n";
print $stdout;
}
);
$loop->add( $process );
Note that until C<on_finish> is invoked, no guarantees are made about how much
of the data actually written by the process is yet in the C<$stdout> scalar.
See also the C<run_child> method of L<IO::Async::Loop>.
To handle data more interactively as it arrives, the C<on_read> key can
instead be used, to provide a callback function to invoke whenever more data
is available from the process.
my $process = IO::Async::Process->new(
command => [ "writing-program", "arguments" ],
stdout => {
on_read => sub {
my ( $stream, $buffref ) = @_;
while( $$buffref =~ s/^(.*)\n// ) {
print "The process wrote a line: $1\n";
}
return 0;
},
},
on_finish => sub {
print "The process has finished\n";
}
);
$loop->add( $process );
If the code to handle data read from the process isn't available yet when
the object is constructed, it can be supplied later by using the C<configure>
method on the C<stdout> filestream at some point before it gets added to the
Loop. In this case, C<stdin> should be configured using C<pipe_read> in the
C<via> key.
my $process = IO::Async::Process->new(
command => [ "writing-program", "arguments" ],
stdout => { via => "pipe_read" },
on_finish => sub {
print "The process has finished\n";
}
);
$process->stdout->configure(
on_read => sub {
my ( $stream, $buffref ) = @_;
while( $$buffref =~ s/^(.*)\n// ) {
print "The process wrote a line: $1\n";
}
return 0;
},
);
$loop->add( $process );
=head2 Sending data to STDIN of a process
By configuring the C<stdin> filehandle of the process using the C<from> key,
data can be written into the C<STDIN> stream of the process.
my $process = IO::Async::Process->new(
command => [ "reading-program", "arguments" ],
stdin => { from => "Here is the data to send\n" },
on_finish => sub {
print "The process has finished\n";
}
);
$loop->add( $process );
The data in this scalar will be written until it is all consumed, then the
handle will be closed. This may be useful if the program waits for EOF on
C<STDIN> before it exits.
To have the ability to write more data into the process once it has started.
the C<write> method on the C<stdin> stream can be used, when it is configured
using the C<pipe_write> value for C<via>:
my $process = IO::Async::Process->new(
command => [ "reading-program", "arguments" ],
stdin => { via => "pipe_write" },
on_finish => sub {
print "The process has finished\n";
}
);
$loop->add( $process );
$process->stdin->write( "Here is some more data\n" );
=cut
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
=cut
0x55AA;
local/lib/perl5/IO/Async/Resolver.pm view on Meta::CPAN
=head1 DESCRIPTION
This module extends an L<IO::Async::Loop> to use the system's name resolver
functions asynchronously. It provides a number of named resolvers, each one
providing an asynchronous wrapper around a single resolver function.
Because the system may not provide asynchronous versions of its resolver
functions, this class is implemented using a L<IO::Async::Function> object
that wraps the normal (blocking) functions. In this case, name resolutions
will be performed asynchronously from the rest of the program, but will likely
be done by a single background worker process, so will be processed in the
order they were requested; a single slow lookup will hold up the queue of
other requests behind it. To mitigate this, multiple worker processes can be
used; see the C<workers> argument to the constructor.
The C<idle_timeout> parameter for the underlying L<IO::Async::Function> object
is set to a default of 30 seconds, and C<min_workers> is set to 0. This
ensures that there are no spare processes sitting idle during the common case
of no outstanding requests.
=cut
sub _init
{
my $self = shift;
my ( $params ) = @_;
$self->SUPER::_init( @_ );
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
use base qw( IO::Async::Notifier );
use Carp;
use IO::Async::OS;
use IO::Async::Process;
=head1 NAME
C<IO::Async::Routine> - execute code in an independent sub-process or thread
=head1 SYNOPSIS
use IO::Async::Routine;
use IO::Async::Channel;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
my $nums_ch = IO::Async::Channel->new;
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
say "The total of 10, 20, 30 is: $$totalref";
$loop->stop;
}
);
$loop->run;
=head1 DESCRIPTION
This L<IO::Async::Notifier> contains a body of code and executes it in a
sub-process or thread, allowing it to act independently of the main program.
Once set up, all communication with the code happens by values passed into or
out of the Routine via L<IO::Async::Channel> objects.
A choice of detachment model is available, with options being a C<fork()>ed
child process, or a thread. In both cases the code contained within the
Routine is free to make blocking calls without stalling the rest of the
program. This makes it useful for using existing code which has no option not
to block within an L<IO::Async>-based program.
Code running inside a C<fork()>-based Routine runs within its own process; it
is isolated from the rest of the program in terms of memory, CPU time, and
other resources. Code running in a thread-based Routine however, shares memory
and other resources such as open filehandles with the main thread.
To create asynchronous wrappers of functions that return a value based only on
their arguments, and do not generally maintain state within the process it may
be more convenient to use an L<IO::Async::Function> instead, which uses an
C<IO::Async::Routine> to contain the body of the function and manages the
Channels itself.
=cut
=head1 EVENTS
=head2 on_finish $exitcode
For C<fork()>-based Routines, this is invoked after the process has exited and
is passed the raw exitcode status.
=head2 on_finish $type, @result
For thread-based Routines, this is invoked after the thread has returned from
its code block and is passed the C<on_joined> result.
As the behaviour of these events differs per model, it may be more convenient
to use C<on_return> and C<on_die> instead.
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
Invoked if the code block fails with an exception.
=cut
=head1 PARAMETERS
The following named parameters may be passed to C<new> or C<configure>:
=head2 model => "fork" | "thread"
Optional. Defines how the routine will detach itself from the main process.
C<fork> uses a child process detached using an L<IO::Async::Process>.
C<thread> uses a thread, and is only available on threaded Perls.
If the model is not specified, the environment variable
C<IO_ASYNC_ROUTINE_MODEL> is used to pick a default. If that isn't defined,
C<fork> is preferred if it is available, otherwise C<thread>.
=head2 channels_in => ARRAY of IO::Async::Channel
ARRAY reference of L<IO::Async::Channel> objects to set up for passing values
in to the Routine.
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
}
push @setup, $wr => "keep";
push @channels_out, [ $ch, $rd, $wr ];
}
my $code = $self->{code};
my $setup = $self->{setup};
push @setup, @$setup if $setup;
my $process = IO::Async::Process->new(
setup => \@setup,
code => sub {
foreach ( @channels_in ) {
my ( $ch, undef, $rd ) = @$_;
$ch->setup_sync_mode( $rd );
}
foreach ( @channels_out ) {
my ( $ch, undef, $wr ) = @$_;
$ch->setup_sync_mode( $wr );
}
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
}
foreach ( @channels_out ) {
my ( $ch, $rd ) = @$_;
$ch->setup_async_mode( read_handle => $rd );
$self->add_child( $ch ) unless $ch->parent;
}
$self->add_child( $self->{process} = $process );
$self->{id} = "P" . $process->pid;
foreach ( @channels_in, @channels_out ) {
my ( undef, undef, $other ) = @$_;
$other->close;
}
}
sub _setup_thread
{
my $self = shift;
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
at the Perl interpreter level, and cannot actually interrupt blocking system
calls.
=cut
sub kill
{
my $self = shift;
my ( $signal ) = @_;
$self->{process}->kill( $signal ) if $self->{model} eq "fork";
threads->object( $self->{tid} )->kill( $signal ) if $self->{model} eq "thread";
}
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
=cut
0x55AA;
local/lib/perl5/IO/Async/Socket.pm view on Meta::CPAN
=head2 recv_all => BOOL
Optional. If true, repeatedly call C<recv> when the receiving handle first
becomes read-ready. By default this is turned off, meaning at most one
fixed-size buffer is received. If there is still more data in the kernel's
buffer, the handle will stil be readable, and will be received from again.
This behaviour allows multiple streams and sockets to be multiplexed
simultaneously, meaning that a large bulk transfer on one cannot starve other
filehandles of processing time. Turning this option on may improve bulk data
transfer rate, at the risk of delaying or stalling processing on other
filehandles.
=head2 send_all => INT
Optional. Analogous to the C<recv_all> option, but for sending. When
C<autoflush> is enabled, this option only affects deferred sending if the
initial attempt failed.
The condition requiring an C<on_recv> handler is checked at the time the
object is added to a Loop; it is allowed to create a C<IO::Async::Socket>
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
again; even if the read buffer is currently empty. See the examples at the end
of this documentation for more detail.
The C<push_on_read> method can be used to insert new, temporary handlers that
take precedence over the global C<on_read> handler. This event is only used if
there are no further pending handlers created by C<push_on_read>.
=head2 on_read_eof
Optional. Invoked when the read handle indicates an end-of-file (EOF)
condition. If there is any data in the buffer still to be processed, the
C<on_read> event will be invoked first, before this one.
=head2 on_write_eof
Optional. Invoked when the write handle indicates an end-of-file (EOF)
condition. Note that this condition can only be detected after a C<write>
syscall returns the C<EPIPE> error. If there is no data pending to be written
then it will not be detected yet.
=head2 on_read_error $errno
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
=head2 read_all => BOOL
Optional. If true, attempt to read as much data from the kernel as possible
when the handle becomes readable. By default this is turned off, meaning at
most one fixed-size buffer is read. If there is still more data in the
kernel's buffer, the handle will still be readable, and will be read from
again.
This behaviour allows multiple streams and sockets to be multiplexed
simultaneously, meaning that a large bulk transfer on one cannot starve other
filehandles of processing time. Turning this option on may improve bulk data
transfer rate, at the risk of delaying or stalling processing on other
filehandles.
=head2 write_len => INT
Optional. Sets the buffer size for C<write> calls. Defaults to 8 KiBytes.
=head2 write_all => BOOL
Optional. Analogous to the C<read_all> option, but for writing. When
C<autoflush> is enabled, this option only affects deferred writing if the
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
my $f = $stream->read_...
If a read EOF or error condition happens while there are read C<Future>s
pending, they are all completed. In the case of a read EOF, they are done with
C<undef>; in the case of a read error they are failed using the C<$!> error
value as the failure.
$f->fail( $message, sysread => $! )
If a read EOF condition happens to the currently-processing read C<Future>, it
will return a partial result. The calling code can detect this by the fact
that the returned data is not complete according to the specification (too
short in C<read_exactly>'s case, or lacking the ending pattern in
C<read_until>'s case). Additionally, each C<Future> will yield the C<$eof>
value in its results.
my ( $string, $eof ) = $f->get;
=cut
local/lib/perl5/IO/Async/Timer/Periodic.pm view on Meta::CPAN
This subclass of L<IO::Async::Timer> implements repeating events at regular
clock intervals. The timing may or may not be subject to how long it takes the
callback to execute. Iterations may be rescheduled runs at fixed regular
intervals beginning at the time the timer was started, or by a fixed delay
after the previous code has finished executing.
For a C<Timer> object that only runs a callback once, after a given delay, see
instead L<IO::Async::Timer::Countdown>. A Countdown timer can also be used to
create repeating events that fire at a fixed delay after the previous event
has finished processing. See als the examples in
C<IO::Async::Timer::Countdown>.
=cut
=head1 EVENTS
The following events are invoked, either using subclass methods or CODE
references in parameters:
=head2 on_tick
local/lib/perl5/IO/Async/Timer/Periodic.pm view on Meta::CPAN
=head2 reschedule => STRING
Optional. Must be one of C<hard>, C<skip> or C<drift>. Defines the algorithm
used to reschedule the next invocation.
C<hard> schedules each iteration at the fixed interval from the previous
iteration's schedule time, ensuring a regular repeating event.
C<skip> schedules similarly to C<hard>, but skips over times that have already
passed. This matters if the duration is particularly short and there's a
possibility that times may be missed, or if the entire process is stopped and
resumed by C<SIGSTOP> or similar.
C<drift> schedules each iteration at the fixed interval from the time that the
previous iteration's event handler returns. This allows it to slowly drift over
time and become desynchronised with other events of the same interval or
multiples/fractions of it.
Once constructed, the timer object will need to be added to the C<Loop> before
it will work. It will also need to be started by the C<start> method.
local/lib/perl5/Module/Build.pm view on Meta::CPAN
fakeinstall html installdirs installsitebin installsitescript installvendorbin
installvendorscript libdoc libhtml pardist ppd ppmdist realclean skipcheck
testall testcover testdb testpod testpodcoverage versioninstall
=head1 NAME
Module::Build - Build and install Perl modules
=head1 SYNOPSIS
Standard process for building & installing modules:
perl Build.PL
./Build
./Build test
./Build install
Or, if you're on a platform (like DOS or Windows) that doesn't require
the "./" notation, you can do this:
perl Build.PL
local/lib/perl5/Module/Build.pm view on Meta::CPAN
C<ExtUtils::MakeMaker>. Developers may alter the behavior of the
module through subclassing in a much more straightforward way than
with C<MakeMaker>. It also does not require a C<make> on your system
- most of the C<Module::Build> code is pure-perl and written in a very
cross-platform way.
See L<"MOTIVATIONS"> for more comparisons between C<ExtUtils::MakeMaker>
and C<Module::Build>.
To install C<Module::Build>, and any other module that uses
C<Module::Build> for its installation process, do the following:
perl Build.PL # 'Build.PL' script creates the 'Build' script
./Build # Need ./ to ensure we're using this "Build" script
./Build test # and not another one that happens to be in the PATH
./Build install
This illustrates initial configuration and the running of three
'actions'. In this case the actions run are 'build' (the default
action), 'test', and 'install'. Other actions defined so far include:
local/lib/perl5/Module/Build.pm view on Meta::CPAN
This is the document you are currently reading. It describes basic
usage and background information. Its main purpose is to assist the
user who wants to learn how to invoke and control C<Module::Build>
scripts at the command line.
=item Authoring Reference (L<Module::Build::Authoring>)
This document describes the structure and organization of
C<Module::Build>, and the relevant concepts needed by authors who are
writing F<Build.PL> scripts for a distribution or controlling
C<Module::Build> processes programmatically.
=item API Reference (L<Module::Build::API>)
This is a reference to the C<Module::Build> API.
=item Cookbook (L<Module::Build::Cookbook>)
This document demonstrates how to accomplish many common tasks. It
covers general command line usage and authoring of F<Build.PL>
scripts. Includes working examples.
local/lib/perl5/Module/Build.pm view on Meta::CPAN
=back
=head1 ACTIONS
There are some general principles at work here. First, each task when
building a module is called an "action". These actions are listed
above; they correspond to the building, testing, installing,
packaging, etc., tasks.
Second, arguments are processed in a very systematic way. Arguments
are always key=value pairs. They may be specified at C<perl Build.PL>
time (i.e. C<perl Build.PL destdir=/my/secret/place>), in which case
their values last for the lifetime of the C<Build> script. They may
also be specified when executing a particular action (i.e.
C<Build test verbose=1>), in which case their values last only for the
lifetime of that command. Per-action command line parameters take
precedence over parameters specified at C<perl Build.PL> time.
The build process also relies heavily on the C<Config.pm> module.
If the user wishes to override any of the
values in C<Config.pm>, she may specify them like so:
perl Build.PL --config cc=gcc --config ld=gcc
The following build actions are provided by default.
=over 4
=item build
local/lib/perl5/Module/Build.pm view on Meta::CPAN
If you run the C<Build> script without any arguments, it runs the
C<build> action, which in turn runs the C<code> and C<docs> actions.
This is analogous to the C<MakeMaker> I<make all> target.
=item clean
[version 0.01]
This action will clean up any files that the build process may have
created, including the C<blib/> directory (but not including the
C<_build/> directory and the C<Build> script itself).
=item code
[version 0.20]
This action builds your code base.
By default it just creates a C<blib/> directory and copies any C<.pm>
and C<.pod> files from your C<lib/> directory into the C<blib/>
directory. It also compiles any C<.xs> files from C<lib/> and places
them in C<blib/>. Of course, you need a working C compiler (probably
the same one that built perl itself) for the compilation to work
properly.
The C<code> action also runs any C<.PL> files in your F<lib/>
directory. Typically these create other files, named the same but
without the C<.PL> ending. For example, a file F<lib/Foo/Bar.pm.PL>
could create the file F<lib/Foo/Bar.pm>. The C<.PL> files are
processed first, so any C<.pm> files (or other kinds that we deal
with) will get copied correctly.
=item config_data
[version 0.26]
...
=item diff
local/lib/perl5/Module/Build.pm view on Meta::CPAN
copies all the files listed in the F<MANIFEST> file to that directory.
This directory is what the distribution tarball is created from.
=item distinstall
[version 0.37]
Performs the 'distdir' action, then switches into that directory and runs a
C<perl Build.PL>, followed by the 'build' and 'install' actions in that
directory. Use PERL_MB_OPT or F<.modulebuildrc> to set options that should be
applied during subprocesses
=item distmeta
[version 0.21]
Creates the F<META.yml> file that describes the distribution.
F<META.yml> is a file containing various bits of I<metadata> about the
distribution. The metadata includes the distribution name, version,
abstract, prerequisites, license, and various other data about the
local/lib/perl5/Module/Build.pm view on Meta::CPAN
distribution, and adds the SIGNATURE file to the distribution's
MANIFEST.
=item disttest
[version 0.05]
Performs the 'distdir' action, then switches into that directory and runs a
C<perl Build.PL>, followed by the 'build' and 'test' actions in that directory.
Use PERL_MB_OPT or F<.modulebuildrc> to set options that should be applied
during subprocesses
=item docs
[version 0.20]
This will generate documentation (e.g. Unix man pages and HTML
documents) for any installable items under B<blib/> that
contain POD. If there are no C<bindoc> or C<libdoc> installation
targets defined (as will be the case on systems that don't support
local/lib/perl5/Module/Build.pm view on Meta::CPAN
This is just like the C<install> action, but it won't actually do
anything, it will just report what it I<would> have done if you had
actually run the C<install> action.
=item help
[version 0.03]
This action will simply print out a message that is meant to help you
use the build process. It will show you a list of available build
actions too.
With an optional argument specifying an action name (e.g. C<Build help
test>), the 'help' action will show you any POD documentation it can
find for that action.
=item html
[version 0.26]
local/lib/perl5/Module/Build.pm view on Meta::CPAN
./Build html --html_links 0
=item install
[version 0.01]
This action will use C<ExtUtils::Install> to install the files from
C<blib/> into the system. See L<"INSTALL PATHS">
for details about how Module::Build determines where to install
things, and how to influence this process.
If you want the installation process to look around in C<@INC> for
other versions of the stuff you're installing and try to delete it,
you can use the C<uninst> parameter, which tells C<ExtUtils::Install> to
do so:
./Build install uninst=1
This can be a good idea, as it helps prevent multiple versions of a
module from being present on your system, which can be a confusing
situation indeed.
local/lib/perl5/Module/Build.pm view on Meta::CPAN
=head1 MOTIVATIONS
There are several reasons I wanted to start over, and not just fix
what I didn't like about C<MakeMaker>:
=over 4
=item *
I don't like the core idea of C<MakeMaker>, namely that C<make> should be
involved in the build process. Here are my reasons:
=over 4
=item +
When a person is installing a Perl module, what can you assume about
their environment? Can you assume they have C<make>? No, but you can
assume they have some version of Perl.
=item +
When a person is writing a Perl module for intended distribution, can
you assume that they know how to build a Makefile, so they can
customize their build process? No, but you can assume they know Perl,
and could customize that way.
=back
For years, these things have been a barrier to people getting the
build/install process to do what they want.
=item *
There are several architectural decisions in C<MakeMaker> that make it
very difficult to customize its behavior. For instance, when using
C<MakeMaker> you do C<use ExtUtils::MakeMaker>, but the object created in
C<WriteMakefile()> is actually blessed into a package name that's
created on the fly, so you can't simply subclass
C<ExtUtils::MakeMaker>. There is a workaround C<MY> package that lets
you override certain C<MakeMaker> methods, but only certain explicitly
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
=over 4
=item current()
[version 0.20]
This method returns a reasonable facsimile of the currently-executing
C<Module::Build> object representing the current build. You can use
this object to query its L</notes()> method, inquire about installed
modules, and so on. This is a great way to share information between
different parts of your build process. For instance, you can ask
the user a question during C<perl Build.PL>, then use their answer
during a regression test:
# In Build.PL:
my $color = $build->prompt("What is your favorite color?");
$build->notes(color => $color);
# In t/colortest.t:
use Module::Build;
my $build = Module::Build->current;
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
to set it to a reasonable default.
The version is extracted from the specified file according to the same
rules as L<ExtUtils::MakeMaker> and C<CPAN.pm>. It involves finding
the first line that matches the regular expression
/([\$*])(([\w\:\']*)\bVERSION)\b.*\=/
eval()-ing that line, then checking the value of the C<$VERSION>
variable. Quite ugly, really, but all the modules on CPAN depend on
this process, so there's no real opportunity to change to something
better.
If the target file of L</dist_version_from> contains more than one package
declaration, the version returned will be the one matching the configured
L</module_name>.
=item dynamic_config
[version 0.07]
A boolean flag indicating whether the F<Build.PL> file must be
executed, or whether this module can be built, tested and installed
solely from consulting its metadata file. The main reason to set this
to a true value is that your module performs some dynamic
configuration as part of its build/install process. If the flag is
omitted, the F<META.yml> spec says that installation tools should
treat it as 1 (true), because this is a safer way to behave.
Currently C<Module::Build> doesn't actually do anything with this flag
- it's up to higher-level tools like C<CPAN.pm> to do something useful
with it. It can potentially bring lots of security, packaging, and
convenience improvements.
=item extra_compiler_flags
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
man pages. One common choice might be C<< utf8 => 1 >> to get Unicode
support.
=item get_options
[version 0.26]
You can pass arbitrary command line options to F<Build.PL> or
F<Build>, and they will be stored in the Module::Build object and can
be accessed via the L</args()> method. However, sometimes you want
more flexibility out of your argument processing than this allows. In
such cases, use the C<get_options> parameter to pass in a hash
reference of argument specifications, and the list of arguments to
F<Build.PL> or F<Build> will be processed according to those
specifications before they're passed on to C<Module::Build>'s own
argument processing.
The supported option specification hash keys are:
=over 4
=item type
The type of option. The types are those supported by Getopt::Long; consult
its documentation for a complete list. Typical types are C<=s> for strings,
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
L<ExtUtils::CBuilder> is automatically added to C<build_requires> if needed.
For a distribution where a compiler is I<optional>, e.g. a dual XS/pure-Perl
distribution, C<needs_compiler> should explicitly be set to a false value.
=item PL_files
[version 0.06]
An optional parameter specifying a set of C<.PL> files in your
distribution. These will be run as Perl scripts prior to processing
the rest of the files in your distribution with the name of the file
they're generating as an argument. They are usually used as templates
for creating other files dynamically, so that a file like
C<lib/Foo/Bar.pm.PL> might create the file C<lib/Foo/Bar.pm>.
The files are specified with the C<.PL> files as hash keys, and the
file(s) they generate as hash values, like so:
my $build = Module::Build->new
(
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
=head2 METHODS
=over 4
=item add_build_element($type)
[version 0.26]
Adds a new type of entry to the build process. Accepts a single
string specifying its type-name. There must also be a method defined
to process things of that type, e.g. if you add a build element called
C<'foo'>, then you must also define a method called
C<process_foo_files()>.
See also
L<Module::Build::Cookbook/"Adding new file types to the build process">.
=item add_to_cleanup(@files)
[version 0.03]
You may call C<< $self->add_to_cleanup(@patterns) >> to tell
C<Module::Build> that certain files should be removed when the user
performs the C<Build clean> action. The arguments to the method are
patterns suitable for passing to Perl's C<glob()> function, specified
in either Unix format or the current machine's native format. It's
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
With a single argument, returns the value of the configuration
variable C<$name>. With two arguments, sets the given configuration
variable to the given value. The value may be any Perl scalar that's
serializable with C<Data::Dumper>. For instance, if you write a
module that can use a MySQL or PostgreSQL back-end, you might create
configuration variables called C<mysql_connect> and
C<postgres_connect>, and set each to an array of connection parameters
for C<< DBI->connect() >>.
Configuration values set in this way using the Module::Build object
will be available for querying during the build/test process and after
installation via the generated C<...::ConfigData> module, as
C<< ...::ConfigData->config($name) >>.
The L<feature()|/"feature($name)"> and C<config_data()> methods represent
Module::Build's main support for configuration of installed modules.
See also L<Module::Build::Authoring/"SAVING CONFIGURATION INFORMATION">.
=item conflicts()
[version 0.21]
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
[version 0.21]
This is a fairly simple wrapper around Perl's C<system()> built-in
command. Given a command and an array of optional arguments, this
method will print the command to C<STDOUT>, and then execute it using
Perl's C<system()>. It returns true or false to indicate success or
failure (the opposite of how C<system()> works, but more intuitive).
Note that if you supply a single argument to C<do_system()>, it
will/may be processed by the system's shell, and any special
characters will do their special things. If you supply multiple
arguments, no shell will get involved and the command will be executed
directly.
=item extra_compiler_flags()
=item extra_compiler_flags(@flags)
[version 0.25]
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
With a single argument, returns true if the given feature is set.
With two arguments, sets the given feature to the given boolean value.
In this context, a "feature" is any optional functionality of an
installed module. For instance, if you write a module that could
optionally support a MySQL or PostgreSQL backend, you might create
features called C<mysql_support> and C<postgres_support>, and set them
to true/false depending on whether the user has the proper databases
installed and configured.
Features set in this way using the Module::Build object will be
available for querying during the build/test process and after
installation via the generated C<...::ConfigData> module, as
C<< ...::ConfigData->feature($name) >>.
The C<feature()> and C<config_data()> methods represent
Module::Build's main support for configuration of installed modules.
See also L<Module::Build::Authoring/"SAVING CONFIGURATION INFORMATION">.
=item fix_shebang_line(@files)
[version 0.??]
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
Asks the user a question and returns their response as a string. The
first argument specifies the message to display to the user (for
example, C<"Where do you keep your money?">). The second argument,
which is optional, specifies a default answer (for example,
C<"wallet">). The user will be asked the question once.
If C<prompt()> detects that it is not running interactively and there
is nothing on STDIN or if the PERL_MM_USE_DEFAULT environment variable
is set to true, the $default will be used without prompting.
To prevent automated processes from blocking, the user must either set
PERL_MM_USE_DEFAULT or attach something to STDIN (this can be a
pipe/file containing a scripted set of answers or /dev/null.)
If no $default is provided an empty string will be used instead. In
non-interactive mode, the absence of $default is an error (though
explicitly passing C<undef()> as the default is valid as of 0.27.)
This method may be called as a class or object method.
=item recommends()
local/lib/perl5/Module/Build/Authoring.pod view on Meta::CPAN
=head2 XS Extensions
Modules which need to compile XS code should list C<ExtUtils::CBuilder>
as a C<build_requires> element.
=head1 SAVING CONFIGURATION INFORMATION
Module::Build provides a very convenient way to save configuration
information that your installed modules (or your regression tests) can
access. If your Build process calls the C<feature()> or
C<config_data()> methods, then a C<Foo::Bar::ConfigData> module will
automatically be created for you, where C<Foo::Bar> is the
C<module_name> parameter as passed to C<new()>. This module provides
access to the data saved by these methods, and a way to update the
values. There is also a utility script called C<config_data>
distributed with Module::Build that provides a command line interface
to this same functionality. See also the generated
C<Foo::Bar::ConfigData> documentation, and the C<config_data>
script's documentation, for more information.
local/lib/perl5/Module/Build/Authoring.pod view on Meta::CPAN
will invoke the entire build/install procedure:
my $build = Module::Build->new(module_name => 'MyModule');
$build->dispatch('build');
$build->dispatch('test');
$build->dispatch('install');
If any of these steps encounters an error, it will throw a fatal
exception.
You can also pass arguments as part of the build process:
my $build = Module::Build->new(module_name => 'MyModule');
$build->dispatch('build');
$build->dispatch('test', verbose => 1);
$build->dispatch('install', sitelib => '/my/secret/place/');
Building and installing modules in this way skips creating the
C<Build> script.
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
my $vals = delete $p->{$_};
foreach my $k (sort keys %$vals) {
$self->$_($k, $vals->{$k});
}
}
}
# The following warning could be unnecessary if the user is running
# an embedded perl, but there aren't too many of those around, and
# embedded perls aren't usually used to install modules, and the
# installation process sometimes needs to run external scripts
# (e.g. to run tests).
$p->{perl} = $self->find_perl_interpreter
or $self->log_warn("Warning: Can't locate your perl binary");
my $blibdir = sub { File::Spec->catdir($p->{blib}, @_) };
$p->{bindoc_dirs} ||= [ $blibdir->("script") ];
$p->{libdoc_dirs} ||= [ $blibdir->("lib"), $blibdir->("arch") ];
$p->{dist_author} = [ $p->{dist_author} ] if defined $p->{dist_author} and not ref $p->{dist_author};
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
$self->recurse_into(\@r);
}
sub cwd {
return Cwd::cwd();
}
sub _quote_args {
# Returns a string that can become [part of] a command line with
# proper quoting so that the subprocess sees this same list of args.
my ($self, @args) = @_;
my @quoted;
for (@args) {
if ( /^[^\s*?!\$<>;\\|'"\[\]\{\}]+$/ ) {
# Looks pretty safe
push @quoted, $_;
} else {
# XXX this will obviously have to improve - is there already a
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
my $cmd = $self->_quote_args(@cmd);
return `$cmd`;
}
}
# Tells us whether the construct open($fh, '-|', @command) is
# supported. It would probably be better to dynamically sense this.
sub have_forkpipe { 1 }
# Determine whether a given binary is the same as the perl
# (configuration) that started this process.
sub _perl_is_same {
my ($self, $perl) = @_;
my @cmd = ($perl);
# When run from the perl core, @INC will include the directories
# where perl is yet to be installed. We need to reference the
# absolute path within the source distribution where it can find
# it's Config.pm This also prevents us from picking up a Config.pm
# from a different configuration that happens to be already
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
my $known_perl;
sub find_perl_interpreter {
my $self = shift;
return $known_perl if defined($known_perl);
return $known_perl = $self->_discover_perl_interpreter;
}
}
# Returns the absolute path of the perl interpreter used to invoke
# this process. The path is derived from $^X or $Config{perlpath}. On
# some platforms $^X contains the complete absolute path of the
# interpreter, on other it may contain a relative path, or simply
# 'perl'. This can also vary depending on whether a path was supplied
# when perl was invoked. Additionally, the value in $^X may omit the
# executable extension on platforms that use one. It's a fatal error
# if the interpreter can't be found because it can result in undefined
# behavior by routines that depend on it (generating errors or
# invoking the wrong perl.)
sub _discover_perl_interpreter {
my $proto = shift;
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
# Create blib/arch to keep blib.pm happy
my $blib = $self->blib;
$self->add_to_cleanup($blib);
File::Path::mkpath( File::Spec->catdir($blib, 'arch') );
if (my $split = $self->autosplit) {
$self->autosplit_file($_, $blib) for ref($split) ? @$split : ($split);
}
foreach my $element (@{$self->build_elements}) {
my $method = "process_${element}_files";
$method = "process_files_by_extension" unless $self->can($method);
$self->$method($element);
}
$self->depends_on('config_data');
}
sub ACTION_build {
my $self = shift;
$self->log_info("Building " . $self->dist_name . "\n");
$self->depends_on('code');
$self->depends_on('docs');
}
sub process_files_by_extension {
my ($self, $ext) = @_;
my $method = "find_${ext}_files";
my $files = $self->can($method) ? $self->$method() : $self->_find_file_by_type($ext, 'lib');
foreach my $file (sort keys %$files) {
$self->copy_if_modified(from => $file, to => File::Spec->catfile($self->blib, $files->{$file}) );
}
}
sub process_support_files {
my $self = shift;
my $p = $self->{properties};
return unless $p->{c_source};
my $files;
if (ref($p->{c_source}) eq "ARRAY") {
push @{$p->{include_dirs}}, @{$p->{c_source}};
for my $path (@{$p->{c_source}}) {
push @$files, @{ $self->rscan_dir($path, $self->file_qr('\.c(c|p|pp|xx|\+\+)?$')) };
}
} else {
push @{$p->{include_dirs}}, $p->{c_source};
$files = $self->rscan_dir($p->{c_source}, $self->file_qr('\.c(c|p|pp|xx|\+\+)?$'));
}
foreach my $file (@$files) {
push @{$p->{objects}}, $self->compile_c($file);
}
}
sub process_share_dir_files {
my $self = shift;
my $files = $self->_find_share_dir_files;
return unless $files;
# root for all File::ShareDir paths
my $share_prefix = File::Spec->catdir($self->blib, qw/lib auto share/);
# copy all share files to blib
foreach my $file (sort keys %$files) {
$self->copy_if_modified(
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
my %files;
for my $dir ( @$list ) {
for my $f ( @{ $self->rscan_dir( $dir, sub {-f} )} ) {
$f =~ s{\A.*?\Q$dir\E/}{};
$files{"$dir/$f"} = "$prefix/$f";
}
}
return %files;
}
sub process_PL_files {
my ($self) = @_;
my $files = $self->find_PL_files;
foreach my $file (sort keys %$files) {
my $to = $files->{$file};
unless ($self->up_to_date( $file, $to )) {
$self->run_perl_script($file, [], [@$to]) or die "$file failed";
$self->add_to_cleanup(@$to);
}
}
}
sub process_xs_files {
my $self = shift;
return if $self->pureperl_only && $self->allow_pureperl;
my $files = $self->find_xs_files;
croak 'Can\'t build xs files under --pureperl-only' if %$files && $self->pureperl_only;
foreach my $from (sort keys %$files) {
my $to = $files->{$from};
unless ($from eq $to) {
$self->add_to_cleanup($to);
$self->copy_if_modified( from => $from, to => $to );
}
$self->process_xs($to);
}
}
sub process_pod_files { shift()->process_files_by_extension(shift()) }
sub process_pm_files { shift()->process_files_by_extension(shift()) }
sub process_script_files {
my $self = shift;
my $files = $self->find_script_files;
return unless keys %$files;
my $script_dir = File::Spec->catdir($self->blib, 'script');
File::Path::mkpath( $script_dir );
foreach my $file (sort keys %$files) {
my $result = $self->copy_if_modified($file, $script_dir, 'flatten') or next;
$self->fix_shebang_line($result) unless $self->is_vmsish;
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
my ($self, $path) = @_;
return File::Spec->catdir( split m{/}, $path );
}
sub fix_shebang_line { # Adapted from fixin() in ExtUtils::MM_Unix 1.35
my ($self, @files) = @_;
my $c = ref($self) ? $self->{config} : 'Module::Build::Config';
my ($does_shbang) = $c->get('sharpbang') =~ /^\s*\#\!/;
for my $file (@files) {
open(my $FIXIN, '<', $file) or die "Can't process '$file': $!";
local $/ = "\n";
chomp(my $line = <$FIXIN>);
next unless $line =~ s/^\s*\#!\s*//; # Not a shebang file.
my ($cmd, $arg) = (split(' ', $line, 2), '');
next unless $cmd =~ /perl/i;
my $interpreter = $self->{properties}{perl};
$self->log_verbose("Changing sharpbang in $file to $interpreter\n");
my $shb = '';
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
sub rscan_dir {
my ($self, $dir, $pattern) = @_;
my @result;
local $_; # find() can overwrite $_, so protect ourselves
my $subr = !$pattern ? sub {push @result, $File::Find::name} :
!ref($pattern) || (ref $pattern eq 'Regexp') ? sub {push @result, $File::Find::name if /$pattern/} :
ref($pattern) eq 'CODE' ? sub {push @result, $File::Find::name if $pattern->()} :
die "Unknown pattern type";
File::Find::find({wanted => $subr, no_chdir => 1, preprocess => sub { sort @_ } }, $dir);
return \@result;
}
sub delete_filetree {
my $self = shift;
my $deleted = 0;
foreach (@_) {
next unless -e $_;
$self->log_verbose("Deleting $_\n");
File::Path::rmtree($_, 0, 0);
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
return $spec->{lib_file};
}
sub compile_xs {
my ($self, $file, %args) = @_;
$self->log_verbose("$file -> $args{outfile}\n");
if (eval {require ExtUtils::ParseXS; 1}) {
ExtUtils::ParseXS::process_file(
filename => $file,
prototypes => 0,
output => $args{outfile},
);
} else {
# Ok, I give up. Just use backticks.
my $xsubpp = Module::Metadata->find_module_by_name('ExtUtils::xsubpp')
or die "Can't find ExtUtils::xsubpp in INC (@INC)";
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
return $self->run_perl_command([@$preargs, $script, @$postargs]);
}
sub run_perl_command {
# XXX Maybe we should accept @args instead of $args? Must resolve
# this before documenting.
my ($self, $args) = @_;
$args = [ $self->split_like_shell($args) ] unless ref($args);
my $perl = ref($self) ? $self->perl : $self->find_perl_interpreter;
# Make sure our local additions to @INC are propagated to the subprocess
local $ENV{PERL5LIB} = join $self->config('path_sep'), $self->_added_to_INC;
return $self->do_system($perl, @$args);
}
# Infer various data from the path of the input filename
# that is needed to create output files.
# The input filename is expected to be of the form:
# lib/Module/Name.ext or Module/Name.ext
sub _infer_xs_spec {
local/lib/perl5/Module/Build/Base.pm view on Meta::CPAN
require DynaLoader;
my $modfname = defined &DynaLoader::mod2fname ? DynaLoader::mod2fname([@d, $file_base]) : $file_base;
$spec{bs_file} = File::Spec->catfile($spec{archdir}, "$modfname.bs");
$spec{lib_file} = File::Spec->catfile($spec{archdir}, "$modfname.".$cf->get('dlext'));
return \%spec;
}
sub process_xs {
my ($self, $file) = @_;
my $spec = $self->_infer_xs_spec($file);
# File name, minus the suffix
(my $file_base = $file) =~ s/\.[^.]+$//;
# .xs -> .c
$self->add_to_cleanup($spec->{c_file});
local/lib/perl5/Module/Build/Compat.pm view on Meta::CPAN
For good measure, of course, test both the F<Makefile.PL> and the
F<Build.PL> before shipping.
=item 3.
Include a F<Build.PL> script and a "pass-through" F<Makefile.PL>
built using C<Module::Build::Compat>. This will mean that people can
continue to use the "old" installation commands, and they may never
notice that it's actually doing something else behind the scenes. It
will also mean that your installation process is compatible with older
versions of tools like CPAN and CPANPLUS.
=back
=head1 AUTHOR
Ken Williams <kwilliams@cpan.org>
local/lib/perl5/Module/Build/Cookbook.pm view on Meta::CPAN
As a best practice, we recommend using the "traditional" style of
F<Makefile.PL> unless your distribution has needs that can't be
accomplished that way.
The C<Module::Build::Compat> module, which is part of
C<Module::Build>'s distribution, is responsible for creating these
F<Makefile.PL>s. Please see L<Module::Build::Compat> for the details.
=head2 Changing the order of the build process
The C<build_elements> property specifies the steps C<Module::Build>
will take when building a distribution. To change the build order,
change the order of the entries in that property:
# Process pod files first
my @e = @{$build->build_elements};
my ($i) = grep {$e[$_] eq 'pod'} 0..$#e;
unshift @e, splice @e, $i, 1;
Currently, C<build_elements> has the following default value:
[qw( PL support pm xs pod script )]
Do take care when altering this property, since there may be
non-obvious (and non-documented!) ordering dependencies in the
C<Module::Build> code.
=head2 Adding new file types to the build process
Sometimes you might have extra types of files that you want to install
alongside the standard types like F<.pm> and F<.pod> files. For
instance, you might have a F<Bar.dat> file containing some data
related to the C<Foo::Bar> module and you'd like for it to end up as
F<Foo/Bar.dat> somewhere in perl's C<@INC> path so C<Foo::Bar> can
access it easily at runtime. The following code from a sample
C<Build.PL> file demonstrates how to accomplish this:
use Module::Build;
local/lib/perl5/Module/Build/Cookbook.pm view on Meta::CPAN
my $build = new Module::Build
(
module_name => 'Foo::Bar',
dat_files => {'some/dir/Bar.dat' => 'lib/Foo/Bar.dat'},
...other stuff here...
);
$build->add_build_element('dat');
$build->create_build_script;
If your extra files actually need to be created on the user's machine,
or if they need some other kind of special processing, you'll probably
want to subclass C<Module::Build> and create a special method to
process them, named C<process_${kind}_files()>:
use Module::Build;
my $class = Module::Build->subclass(code => <<'EOF');
sub process_dat_files {
my $self = shift;
... locate and process *.dat files,
... and create something in blib/lib/
}
EOF
my $build = $class->new
(
module_name => 'Foo::Bar',
...other stuff here...
);
$build->add_build_element('dat');
$build->create_build_script;
If your extra files don't go in F<lib/> but in some other place, see
L<"Adding new elements to the install process"> for how to actually
get them installed.
Please note that these examples use some capabilities of Module::Build
that first appeared in version 0.26. Before that it could
still be done, but the simple cases took a bit more work.
=head2 Adding new elements to the install process
By default, Module::Build creates seven subdirectories of the F<blib>
directory during the build process: F<lib>, F<arch>, F<bin>,
F<script>, F<bindoc>, F<libdoc>, and F<html> (some of these may be
missing or empty if there's nothing to go in them). Anything copied
to these directories during the build will eventually be installed
during the C<install> action (see L<Module::Build/"INSTALL PATHS">.
If you need to create a new custom type of installable element, e.g. C<conf>,
then you need to tell Module::Build where things in F<blib/conf/>
should be installed. To do this, use the C<install_path> parameter to
the C<new()> method:
local/lib/perl5/Module/Build/Cookbook.pm view on Meta::CPAN
The user may also specify the path on the command line:
perl Build.PL --install_path conf=/foo/path/etc
The important part, though, is that I<somehow> the install path needs
to be set, or else nothing in the F<blib/conf/> directory will get
installed, and a runtime error during the C<install> action will
result.
See also L<"Adding new file types to the build process"> for how to
create the stuff in F<blib/conf/> in the first place.
=head1 EXAMPLES ON CPAN
Several distributions on CPAN are making good use of various features
of Module::Build. They can serve as real-world examples for others.
=head2 SVN-Notify-Mirror
local/lib/perl5/Module/Build/Platform/VMS.pm view on Meta::CPAN
=item _quote_args
Command-line arguments (but not the command itself) must be quoted
to ensure case preservation.
=cut
sub _quote_args {
# Returns a string that can become [part of] a command line with
# proper quoting so that the subprocess sees this same list of args,
# or if we get a single arg that is an array reference, quote the
# elements of it and return the reference.
my ($self, @args) = @_;
my $got_arrayref = (scalar(@args) == 1
&& ref $args[0] eq 'ARRAY')
? 1
: 0;
# Do not quote qualifiers that begin with '/'.
map { if (!/^\//) {
local/lib/perl5/Module/Build/Platform/Windows.pm view on Meta::CPAN
print $out @file[$skiplines..$#file];
print $out $tail unless $taildone;
close($out);
return $opts{out};
}
sub _quote_args {
# Returns a string that can become [part of] a command line with
# proper quoting so that the subprocess sees this same list of args.
my ($self, @args) = @_;
my @quoted;
for (@args) {
if ( /^[^\s*?!\$<>;|'"\[\]\{\}]+$/ ) {
# Looks pretty safe
push @quoted, $_;
} else {
# XXX this will obviously have to improve - is there already a