view release on metacpan or search on metacpan
local/lib/perl5/Future.pm view on Meta::CPAN
{
my ( $cb ) = @_;
defined $cb and ( reftype($cb) eq 'CODE' || overload::Method($cb, '&{}') );
}
sub new
{
my $proto = shift;
return bless {
ready => 0,
callbacks => [], # [] = [$type, ...]
( DEBUG ?
( do { my $at = Carp::shortmess( "constructed" );
chomp $at; $at =~ s/\.$//;
constructed_at => $at } )
: () ),
( $TIMES ?
( btime => [ gettimeofday ] )
: () ),
}, ( ref $proto || $proto );
}
local/lib/perl5/Future.pm view on Meta::CPAN
{
my $self = shift;
$self->{ready} = 1;
$self->{ready_at} = _shortmess $_[0] if DEBUG;
if( $TIMES ) {
$self->{rtime} = [ gettimeofday ];
}
delete $self->{on_cancel};
my $callbacks = delete $self->{callbacks} or return;
my $cancelled = $self->{cancelled};
my $fail = defined $self->{failure};
my $done = !$fail && !$cancelled;
my @result = $done ? $self->get :
$fail ? $self->failure :
();
foreach my $cb ( @$callbacks ) {
my ( $flags, $code ) = @$cb;
my $is_future = blessed( $code ) && $code->isa( "Future" );
next if $done and not( $flags & CB_DONE );
next if $fail and not( $flags & CB_FAIL );
next if $cancelled and not( $flags & CB_CANCEL );
$self->{reported} = 1 if $fail;
if( $is_future ) {
local/lib/perl5/Future.pm view on Meta::CPAN
$fseq->on_cancel( $f2 );
}
else {
$f2 = $self;
}
if( $f2->is_ready ) {
$f2->on_ready( $fseq ) if !$f2->{cancelled};
}
else {
push @{ $f2->{callbacks} }, [ CB_DONE|CB_FAIL, $fseq ];
weaken( $f2->{callbacks}[-1][1] );
}
}
else {
$code->(
( $flags & CB_SELF ? $self : () ),
( $flags & CB_RESULT ? @result : () ),
);
}
}
}
local/lib/perl5/Future.pm view on Meta::CPAN
}
=head2 on_cancel
$future->on_cancel( $code )
If the future is not yet ready, adds a callback to be invoked if the future is
cancelled by the C<cancel> method. If the future is already ready, throws an
exception.
If the future is cancelled, the callbacks will be invoked in the reverse order
to that in which they were registered.
$on_cancel->( $future )
If passed another C<Future> instance, the passed instance will be cancelled
when the original future is cancelled. This method does nothing if the future
is already complete.
=cut
local/lib/perl5/Future.pm view on Meta::CPAN
my $done = !$fail && !$self->{cancelled};
$self->{reported} = 1 if $fail;
$is_future ? ( $done ? $code->done( $self->get ) :
$fail ? $code->fail( $self->failure ) :
$code->cancel )
: $code->( $self );
}
else {
push @{ $self->{callbacks} }, [ CB_ALWAYS|CB_SELF, $self->wrap_cb( on_ready => $code ) ];
}
return $self;
}
=head2 is_done
$done = $future->is_done
Returns true on a future if it is ready and completed successfully. Returns
local/lib/perl5/Future.pm view on Meta::CPAN
$is_future or _callable( $code ) or
Carp::croak "Expected \$code to be callable or a Future in ->on_done";
if( $self->{ready} ) {
return $self if $self->{failure} or $self->{cancelled};
$is_future ? $code->done( $self->get )
: $code->( $self->get );
}
else {
push @{ $self->{callbacks} }, [ CB_DONE|CB_RESULT, $self->wrap_cb( on_done => $code ) ];
}
return $self;
}
=head2 is_failed
$failed = $future->is_failed
I<Since version 0.26.>
local/lib/perl5/Future.pm view on Meta::CPAN
Carp::croak "Expected \$code to be callable or a Future in ->on_fail";
if( $self->{ready} ) {
return $self if not $self->{failure};
$self->{reported} = 1;
$is_future ? $code->fail( $self->failure )
: $code->( $self->failure );
}
else {
push @{ $self->{callbacks} }, [ CB_FAIL|CB_RESULT, $self->wrap_cb( on_fail => $code ) ];
}
return $self;
}
=head2 cancel
$future->cancel
Requests that the future be cancelled, immediately marking it as ready. This
local/lib/perl5/Future.pm view on Meta::CPAN
return $fseq;
}
my $fseq = $f1->new;
$fseq->on_cancel( $f1 );
# TODO: if anyone cares about the op name, we might have to synthesize it
# from $flags
$code = $f1->wrap_cb( sequence => $code ) unless $flags & (CB_SEQ_IMDONE|CB_SEQ_IMFAIL);
push @{ $f1->{callbacks} }, [ CB_DONE|CB_FAIL|$flags, $code, $fseq ];
weaken( $f1->{callbacks}[-1][2] );
return $fseq;
}
=head2 then
$future = $f1->then( \&done_code )
I<Since version 0.13.>
local/lib/perl5/Future.pm view on Meta::CPAN
implementation simply returns the callback agument as-is; the method is
provided to allow users to provide extra behaviour. This can be done by
applying a method modifier of the C<around> kind, so in effect add a chain of
wrappers. Each wrapper can then perform its own wrapping logic of the
callback. C<$operation_name> is a string giving the reason for which the
callback is being saved; currently one of C<on_ready>, C<on_done>, C<on_fail>
or C<sequence>; the latter being used for all the sequence-returning methods.
This method is intentionally invoked only for CODE references that are being
saved on a pending C<Future> instance to be invoked at some later point. It
does not run for callbacks to be invoked on an already-complete instance. This
is for performance reasons, where the intended behaviour is that the wrapper
can provide some amount of context save and restore, to return the operating
environment for the callback back to what it was at the time it was saved.
For example, the following wrapper saves the value of a package variable at
the time the callback was saved, and restores that value at invocation time
later on. This could be useful for preserving context during logging in a
Future-based program.
our $LOGGING_CTX;
local/lib/perl5/Future.pm view on Meta::CPAN
my $cb = $orig->( @_ );
my $saved_logging_ctx = $LOGGING_CTX;
return sub {
local $LOGGING_CTX = $saved_logging_ctx;
$cb->( @_ );
};
};
At this point, any code deferred into a C<Future> by any of its callbacks will
observe the C<$LOGGING_CTX> variable as having the value it held at the time
the callback was saved, even if it is invoked later on when that value is
different.
Remember when writing such a wrapper, that it still needs to invoke the
previous version of the method, so that it plays nicely in combination with
others (see the C<< $orig->( @_ ) >> part).
=cut
local/lib/perl5/IO/Async.pm view on Meta::CPAN
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
L<IO::Async::Socket> class is another subclass of L<IO::Async::Handle> which
maintains an outgoing packet queue, and informs of packet receipt using a
callback or method.
The L<IO::Async::Listener> class is another subclass of L<IO::Async::Handle>
which facilitates the use of C<listen(2)>-mode sockets. When a new connection
local/lib/perl5/IO/Async.pm view on Meta::CPAN
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:
local/lib/perl5/IO/Async.pm view on Meta::CPAN
bytes or a POSIX signal.
Futures are a recent addition to the C<IO::Async> API and details are still
subject to change and experimentation.
In general, methods that support Futures return a new Future object to
represent the outstanding operation. If callback functions are supplied as
well, these will be fired in addition to the Future object becoming ready. Any
failures that are reported will, in general, use the same conventions for the
Future's C<fail> arguments to relate it to the legacy C<on_error>-style
callbacks.
$on_NAME_error->( $message, @argmuents )
$f->fail( $message, NAME, @arguments )
where C<$message> is a message intended for humans to read (so that this is
the message displayed by C<< $f->get >> if the failure is not otherwise
caught), C<NAME> is the name of the failing operation. If the failure is due
to a failed system call, the value of C<$!> will be the final argument. The
message should not end with a linefeed.
local/lib/perl5/IO/Async/Channel.pm view on Meta::CPAN
return $self->_recv_sync( @_ ) if $self->{mode} eq "sync";
return $self->_recv_async( @_ ) if $self->{mode} eq "async";
}
=head2 close
$channel->close
Closes the channel. Causes a pending C<recv> on the other end to return undef
or the queued C<on_eof> callbacks to be invoked.
=cut
sub close
{
my $self = shift;
return $self->_close_sync if $self->{mode} eq "sync";
return $self->_close_async if $self->{mode} eq "async";
}
local/lib/perl5/IO/Async/Handle.pm view on Meta::CPAN
use IO::Handle; # give methods to bare IO handles
use Future;
use Future::Utils qw( try_repeat );
use IO::Async::OS;
=head1 NAME
C<IO::Async::Handle> - event callbacks for a non-blocking file descriptor
=head1 SYNOPSIS
This class is likely not to be used directly, because subclasses of it exist
to handle more specific cases. Here is an example of how it would be used to
watch a listening socket for new connections. In real code, it is likely that
the C<< Loop->listen >> method would be used instead.
use IO::Socket::INET;
use IO::Async::Handle;
local/lib/perl5/IO/Async/Handle.pm view on Meta::CPAN
=head2 want_writeready => BOOL
If present, enable or disable read- or write-ready notification as per the
C<want_readready> and C<want_writeready> methods.
It is required that a matching C<on_read_ready> or C<on_write_ready> are
available for any handle that is provided; either passed as a callback CODE
reference or as an overridden the method. I.e. if only a C<read_handle> is
given, then C<on_write_ready> can be absent. If C<handle> is used as a
shortcut, then both read and write-ready callbacks or methods are required.
If no IO handles are provided at construction time, the object is still
created but will not yet be fully-functional as a Handle. IO handles can be
assigned later using the C<set_handle> or C<set_handles> methods, or by
C<configure>. This may be useful when constructing an object to represent a
network connection, before the C<connect(2)> has actually been performed yet.
=cut
sub configure
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
$class->API_VERSION >= NEED_API_VERSION or
die "$class is too old for IO::Async $VERSION; we need API version >= ".NEED_API_VERSION.", it provides ".$class->API_VERSION."\n";
WATCHDOG_ENABLE and !$class->_CAN_WATCHDOG and
warn "$class cannot implement IO_ASYNC_WATCHDOG\n";
my $self = bless {
notifiers => {}, # {nkey} = notifier
iowatches => {}, # {fd} = [ $on_read_ready, $on_write_ready, $on_hangup ]
sigattaches => {}, # {sig} => \@callbacks
childmanager => undef,
childwatches => {}, # {pid} => $code
threadwatches => {}, # {tid} => $code
timequeue => undef,
deferrals => [],
os => {}, # A generic scratchpad for IO::Async::OS to store whatever it wants
}, $class;
# It's possible this is a specific subclass constructor. We still want the
# magic IO::Async::Loop->new constructor to yield this if it's the first
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=cut
=head2 loop_once
$count = $loop->loop_once( $timeout )
This method performs a single wait loop using the specific subclass's
underlying mechanism. If C<$timeout> is undef, then no timeout is applied, and
it will wait until an event occurs. The intention of the return value is to
indicate the number of callbacks that this loop executed, though different
subclasses vary in how accurately they can report this. See the documentation
for this method in the specific subclass for more information.
=cut
sub loop_once
{
my $self = shift;
my ( $timeout ) = @_;
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
return $self->$method(
%params,
( @others ? ( extensions => \@others ) : () ),
);
}
my $handle = $params{handle};
my $on_done;
# Legacy callbacks
if( my $on_connected = delete $params{on_connected} ) {
$on_done = $on_connected;
}
elsif( my $on_stream = delete $params{on_stream} ) {
defined $handle and croak "Cannot pass 'on_stream' with a handle object as well";
require IO::Async::Stream;
# TODO: It doesn't make sense to put a SOCK_DGRAM in an
# IO::Async::Stream but currently we don't detect this
$handle = IO::Async::Stream->new;
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=item on_read_ready => BOOL
If true, remove the watch for read-readiness.
=item on_write_ready => BOOL
If true, remove the watch for write-readiness.
=back
Either or both callbacks may be removed at once. It is not an error to attempt
to remove a callback that is not present. If both callbacks were provided to
the C<watch_io> method and only one is removed by this method, the other shall
remain.
=cut
sub __unwatch_io
{
my $self = shift;
my %params = @_;
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
}
elsif( !defined $$timeref or $timer_delay < $$timeref ) {
$$timeref = $timer_delay;
}
}
=head2 _manage_queues
$loop->_manage_queues
Checks the timer queue for callbacks that should have been invoked by now, and
runs them all, removing them from the queue. It also invokes all of the
pending idle handlers. Any new idle handlers installed by these are not
invoked yet; they will wait for the next time this method is called.
=cut
sub _manage_queues
{
my $self = shift;
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
This functionality is generic and not limited to C<SSL>; other extensions may
also use it.
The following methods take an C<extensions> parameter:
$loop->connect
$loop->listen
If an extension C<listen> method is invoked, it will be passed a C<listener>
parameter even if one was not provided to the original C<< $loop->listen >>
call, and it will not receive any of the C<on_*> event callbacks. It should
use the C<acceptor> parameter on the C<listener> object.
=cut
=head1 STALL WATCHDOG
A well-behaved L<IO::Async> program should spend almost all of its time
blocked on input using the underlying C<IO::Async::Loop> instance. The stall
watchdog is an optional debugging feature to help detect CPU spinlocks and
other bugs, where control is not returned to the loop every so often.
local/lib/perl5/IO/Async/Loop/Poll.pm view on Meta::CPAN
=head1 METHODS
=cut
=head2 post_poll
$count = $loop->post_poll
This method checks the returned event list from a C<IO::Poll::poll> call,
and calls any of the notification methods or callbacks that are appropriate.
It returns the total number of callbacks that were invoked; that is, the
total number of C<on_read_ready> and C<on_write_ready> callbacks for
C<watch_io>, and C<watch_time> event callbacks.
=cut
sub post_poll
{
my $self = shift;
my $iowatches = $self->{iowatches};
my $poll = $self->{poll};
local/lib/perl5/IO/Async/Loop/Poll.pm view on Meta::CPAN
return $count;
}
=head2 loop_once
$count = $loop->loop_once( $timeout )
This method calls the C<poll> method on the stored C<IO::Poll> object,
passing in the value of C<$timeout>, and then runs the C<post_poll> method
on itself. It returns the total number of callbacks invoked by the
C<post_poll> method, or C<undef> if the underlying C<poll> method returned
an error.
=cut
sub loop_once
{
my $self = shift;
my ( $timeout ) = @_;
local/lib/perl5/IO/Async/Loop/Select.pm view on Meta::CPAN
=head1 DESCRIPTION
This subclass of L<IO::Async::Loop> uses the C<select(2)> syscall to perform
read-ready and write-ready tests.
To integrate with an existing C<select>-based event loop, a pair of methods
C<pre_select> and C<post_select> can be called immediately before and
after a C<select> call. The relevant bits in the read-ready, write-ready and
exceptional-state bitvectors are set by the C<pre_select> method, and tested
by the C<post_select> method to pick which event callbacks to invoke.
=cut
=head1 CONSTRUCTOR
=cut
=head2 new
$loop = IO::Async::Loop::Select->new
local/lib/perl5/IO/Async/Loop/Select.pm view on Meta::CPAN
}
return;
}
=head2 post_select
$loop->post_select( $readvec, $writevec, $exceptvec )
This method checks the returned bitvectors from a C<select> call, and calls
any of the callbacks that are appropriate.
=over 8
=item $readvec
=item $writevec
=item $exceptvec
Scalars containing the read-ready, write-ready and exception bitvectors
local/lib/perl5/IO/Async/Loop/Select.pm view on Meta::CPAN
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/Notifier.pm view on Meta::CPAN
a tree structure, where any Notifier can contain a collection of children.
Normally, objects in this class would not be directly used by an end program,
as it performs no actual IO work, and generates no actual events. These are all
left to the various subclasses, such as:
=over 4
=item *
L<IO::Async::Handle> - event callbacks for a non-blocking file descriptor
=item *
L<IO::Async::Stream> - event callbacks and write bufering for a stream
filehandle
=item *
L<IO::Async::Socket> - event callbacks and send buffering for a socket
filehandle
=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
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
sub _remove_from_loop
{
my $self = shift;
my ( $loop ) = @_;
# Code here to undo the event handling set up above
}
Since all the methods documented here will be available, the implementation
may wish to use the C<configure> and C<make_event_cb> or C<invoke_event>
methods to implement its own event callbacks.
=cut
=head1 EVENTS
The following events are invoked, either using subclass methods or CODE
references in parameters:
=head2 on_error $message, $name, @details
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
For example,
my $mref = $notifier->_replace_weakself( sub {
my ( $notifier, $arg ) = @_;
print "Notifier $notifier got argument $arg\n";
} );
$mref->( $object, 123 );
This is provided as a utility for Notifier subclasses to use for event
callbacks on other objects, where the delegated object is passed in the
function's arguments.
The C<$code> argument may also be a plain string, which will be used as a
method name; the returned CODE ref will then invoke that method on the object.
As with C<_capture_weakself> this is stored symbolically.
As with C<_capture_weakself>, care should be taken against Notifier
destruction if the C<$mref> CODE reference is stored in some other object.
=cut
local/lib/perl5/IO/Async/Socket.pm view on Meta::CPAN
our $VERSION = '0.70';
use base qw( IO::Async::Handle );
use Errno qw( EAGAIN EWOULDBLOCK EINTR );
use Carp;
=head1 NAME
C<IO::Async::Socket> - event callbacks and send buffering for a socket
filehandle
=head1 SYNOPSIS
use IO::Async::Socket;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
my $socket = IO::Async::Socket->new(
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
# Bitfields in the want flags
use constant WANT_READ_FOR_READ => 0x01;
use constant WANT_READ_FOR_WRITE => 0x02;
use constant WANT_WRITE_FOR_READ => 0x04;
use constant WANT_WRITE_FOR_WRITE => 0x08;
use constant WANT_ANY_READ => WANT_READ_FOR_READ |WANT_READ_FOR_WRITE;
use constant WANT_ANY_WRITE => WANT_WRITE_FOR_READ|WANT_WRITE_FOR_WRITE;
=head1 NAME
C<IO::Async::Stream> - event callbacks and write bufering for a stream
filehandle
=head1 SYNOPSIS
use IO::Async::Stream;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
my $stream = IO::Async::Stream->new(