Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
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
it.
=cut
=head1 AS A MIXIN
Rather than being used as a subclass this package also supports being used as
a non-principle superclass for an object, as a mix-in. It still provides
methods and satisfies an C<isa> test, even though the constructor is not
directly called. This simply requires that the object be based on a normal
blessed hash reference and include C<IO::Async::Notifier> somewhere in its
C<@ISA> list.
The methods in this class all use only keys in the hash prefixed by
C<"IO_Async_Notifier__"> for namespace purposes.
This is intended mainly for defining a subclass of some other object that is
also an C<IO::Async::Notifier>, suitable to be added to an L<IO::Async::Loop>.
package SomeEventSource::Async;
use base qw( SomeEventSource IO::Async::Notifier );
sub _add_to_loop
{
my $self = shift;
my ( $loop ) = @_;
# Code here to set up event handling on $loop that may be required
}
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
Invoked by C<invoke_error>.
=cut
=head1 PARAMETERS
A specific subclass of C<IO::Async::Notifier> defines named parameters that
control its behaviour. These may be passed to the C<new> constructor, or to
the C<configure> method. The documentation on each specific subclass will give
details on the parameters that exist, and their uses. Some parameters may only
support being set once at construction time, or only support being changed if
the object is in a particular state.
The following parameters are supported by all Notifiers:
=over 8
=item on_error => CODE
CODE reference for event handler.
=item notifier_name => STRING
Optional string used to identify this particular Notifier. This value will be
returned by the C<notifier_name> method.
=back
=cut
=head1 CONSTRUCTOR
=cut
=head2 new
$notifier = IO::Async::Notifier->new( %params )
This function returns a new instance of a C<IO::Async::Notifier> object with
the given initial values of the named parameters.
Up until L<IO::Async> version 0.19, this module used to implement the IO
handle features now found in the L<IO::Async::Handle> subclass. Code that
needs to use any of C<handle>, C<read_handle>, C<write_handle>,
C<on_read_ready> or C<on_write_ready> should use L<IO::Async::Handle> instead.
=cut
sub new
{
my $class = shift;
my %params = @_;
my $self = bless {}, $class;
$self->_init( \%params );
$self->configure( %params );
return $self;
}
=head1 METHODS
=cut
=head2 configure
$notifier->configure( %params )
Adjust the named parameters of the C<Notifier> as given by the C<%params>
hash.
=cut
# for subclasses to override and call down to
sub configure
{
my $self = shift;
my %params = @_;
foreach (qw( notifier_name on_error )) {
$self->{"IO_Async_Notifier__$_"} = delete $params{$_} if exists $params{$_};
}
$self->configure_unknown( %params ) if keys %params;
}
sub configure_unknown
{
my $self = shift;
my %params = @_;
my $class = ref $self;
croak "Unrecognised configuration keys for $class - " . join( " ", keys %params );
}
=head2 loop
$loop = $notifier->loop
Returns the L<IO::Async::Loop> that this Notifier is a member of.
=cut
sub loop
{
my $self = shift;
return $self->{IO_Async_Notifier__loop}
}
*get_loop = \&loop;
# Only called by IO::Async::Loop, not external interface
sub __set_loop
{
my $self = shift;
my ( $loop ) = @_;
# early exit if no change
return if !$loop and !$self->loop or
$loop and $self->loop and $loop == $self->loop;
$self->_remove_from_loop( $self->loop ) if $self->loop;
$self->{IO_Async_Notifier__loop} = $loop;
weaken( $self->{IO_Async_Notifier__loop} ); # To avoid a cycle
$self->_add_to_loop( $self->loop ) if $self->loop;
}
=head2 notifier_name
$name = $notifier->notifier_name
Returns the name to identify this Notifier. If a has not been set, it will
return the empty string. Subclasses may wish to override this behaviour to
return some more useful information, perhaps from configured parameters.
=cut
sub notifier_name
{
my $self = shift;
return $self->{IO_Async_Notifier__notifier_name} || "";
}
=head2 adopt_future
$f = $notifier->adopt_future( $f )
Stores a reference to the L<Future> instance within the notifier itself, so
the reference doesn't get lost. This reference will be dropped when the future
becomes ready (either by success or failure). Additionally, if the future
failed the notifier's C<invoke_error> method will be informed.
This means that if the notifier does not provide an C<on_error> handler, nor
is there one anywhere in the parent chain, this will be fatal to the caller of
C<< $f->fail >>. To avoid this being fatal if the failure is handled
elsewhere, use the C<else_done> method on the future to obtain a sequence one
that never fails.
$notifier->adopt_future( $f->else_done() )
The future itself is returned.
=cut
sub adopt_future
{
my $self = shift;
my ( $f ) = @_;
my $fkey = "$f"; # stable stringification
$self->{IO_Async_Notifier__futures}{$fkey} = $f;
$f->on_ready( $self->_capture_weakself( sub {
my $self = shift;
my ( $f ) = @_;
delete $self->{IO_Async_Notifier__futures}{$fkey};
$self->invoke_error( $f->failure ) if $f->is_failed;
}));
return $f;
}
=head1 CHILD NOTIFIERS
During the execution of a program, it may be the case that certain IO handles
cause other handles to be created; for example, new sockets that have been
C<accept()>ed from a listening socket. To facilitate these, a notifier may
contain child notifier objects, that are automatically added to or removed
from the L<IO::Async::Loop> that manages their parent.
=cut
=head2 parent
$parent = $notifier->parent
Returns the parent of the notifier, or C<undef> if does not have one.
=cut
sub parent
{
my $self = shift;
return $self->{IO_Async_Notifier__parent};
}
=head2 children
@children = $notifier->children
Returns a list of the child notifiers contained within this one.
=cut
sub children
{
my $self = shift;
return unless $self->{IO_Async_Notifier__children};
return @{ $self->{IO_Async_Notifier__children} };
}
=head2 add_child
$notifier->add_child( $child )
Adds a child notifier. This notifier will be added to the containing loop, if
the parent has one. Only a notifier that does not currently have a parent and
is not currently a member of any loop may be added as a child. If the child
itself has grandchildren, these will be recursively added to the containing
loop.
=cut
sub add_child
{
my $self = shift;
my ( $child ) = @_;
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
IO::Async:: => Ia:
Net::Async:: => Na:
Finally, each notifier that has a name defined using the C<notifier_name>
parameter has that name appended in braces.
For example, invoking
$stream->debug_printf( "EVENT on_read" )
On an L<IO::Async::Stream> instance reading and writing a file descriptor
whose C<fileno> is 4, which is a child of an L<IO::Async::Protocol::Stream>,
will produce a line of output:
[Ia:Stream{rw=4}<-IaP:Stream] EVENT on_read
=cut
sub debug_printf
{
$IO::Async::Debug::DEBUG or return;
my $self = shift;
my ( $format, @args ) = @_;
my @id;
while( $self ) {
push @id, ref $self;
my $name = $self->notifier_name;
$id[-1] .= "{$name}" if defined $name and length $name;
$self = $self->parent;
}
s/^IO::Async::Protocol::/IaP:/,
s/^IO::Async::/Ia:/,
s/^Net::Async::/Na:/ for @id;
IO::Async::Debug::logf "[%s] $format\n", join("<-", @id), @args;
}
sub _debug_printf_event
{
my $self = shift;
my ( $caller, $event_name ) = @_;
my $class = ref $self;
if( $IO::Async::Debug::DEBUG > 1 or $class eq $caller ) {
s/^IO::Async::Protocol::/IaP:/,
s/^IO::Async::/Ia:/,
s/^Net::Async::/Na:/ for my $str_caller = $caller;
$self->debug_printf( "EVENT %s",
( $class eq $caller ? $event_name : "${str_caller}::$event_name" )
);
}
}
=head2 invoke_error
$notifier->invoke_error( $message, $name, @details )
Invokes the stored C<on_error> event handler, passing in the given arguments.
If no handler is defined, it will be passed up to the containing parent
notifier, if one exists. If no parent exists, the error message will be thrown
as an exception by using C<die()> and this method will not return.
If a handler is found to handle this error, the method will return as normal.
However, as the expected use-case is to handle "fatal" errors that now render
the notifier unsuitable to continue, code should be careful not to perform any
further work after invoking it. Specifically, sockets may become disconnected,
or the entire notifier may now be removed from its containing loop.
The C<$name> and C<@details> list should follow similar semantics to L<Future>
failures. That is, the C<$name> should be a string giving a category of
failure, and the C<@details> list should contain additional arguments that
relate to that kind of failure.
=cut
sub invoke_error
{
my $self = shift;
my ( $message, $name, @details ) = @_;
if( my $code = $self->{IO_Async_Notifier__on_error} || $self->can( "on_error" ) ) {
return $code->( $self, $message, $name, @details );
}
if( my $parent = $self->parent ) {
return $parent->invoke_error( @_ );
}
die "$message\n";
}
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
=cut
0x55AA;
( run in 0.526 second using v1.01-cache-2.11-cpan-140bd7fdf52 )