AnyEvent

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

7.17 Wed Sep 18 03:04:49 CEST 2019
	- work around antique openssl version in RHEL 7  by formatting
          dh parameters differently (reported by several people).
	- add t/13_weaken.t.

7.16 Fri Jul 19 18:00:21 CEST 2019
	- add ffdhe group dh parameters from RFC 7919, and use ffdhe3072
          as new default, instead of schmorp1539.
        - AnyEvent::Log did not reassess logging status of
          AnyEvent::Log::logger's when contexts were changed with
          ->attach/detach/slaves, causing them to not log even though a
          recent attach should have caused them to log.
	- added some more logging configuration examples.
        - mention RFC 8482 in AnyEvent::DNS.

7.15 Tue Feb 26 03:07:42 CET 2019
        - INCOMPATIBLE CHANGE: AnyEvent::Handle's tls_detect documentation gave
          separate major and minor versions, while code passed only a single
          value. This version follows the documentation and now passes separate
          major and minor values.
	- work around Net::SSLeay not having been ported to openssl 1.1, but many
          distributions compiling it against openssl 1.1, which unfortunately

README  view on Meta::CPAN

    Perl signals can be either "safe" (synchronous to opcode handling) or
    "unsafe" (asynchronous) - the former might delay signal delivery
    indefinitely, the latter might corrupt your memory.

    AnyEvent signal handlers are, in addition, synchronous to the event
    loop, i.e. they will not interrupt your running perl program but will
    only be called as part of the normal event handling (just like timer,
    I/O etc. callbacks, too).

   Signal Races, Delays and Workarounds
    Many event loops (e.g. Glib, Tk, Qt, IO::Async) do not support attaching
    callbacks to signals in a generic way, which is a pity, as you cannot do
    race-free signal handling in perl, requiring C libraries for this.
    AnyEvent will try to do its best, which means in some cases, signals
    will be delayed. The maximum time a signal might be delayed is 10
    seconds by default, but can be overriden via
    $ENV{PERL_ANYEVENT_MAX_SIGNAL_LATENCY} or $AnyEvent::MAX_SIGNAL_LATENCY
    - see the "ENVIRONMENT VARIABLES" section for details.

    All these problems can be avoided by installing the optional
    Async::Interrupt module, which works with most event loops. It will not

lib/AnyEvent.pm  view on Meta::CPAN

indefinitely, the latter might corrupt your memory.

AnyEvent signal handlers are, in addition, synchronous to the event loop,
i.e. they will not interrupt your running perl program but will only be
called as part of the normal event handling (just like timer, I/O etc.
callbacks, too).

=head3 Signal Races, Delays and Workarounds

Many event loops (e.g. Glib, Tk, Qt, IO::Async) do not support
attaching callbacks to signals in a generic way, which is a pity,
as you cannot do race-free signal handling in perl, requiring
C libraries for this. AnyEvent will try to do its best, which
means in some cases, signals will be delayed. The maximum time
a signal might be delayed is 10 seconds by default, but can
be overriden via C<$ENV{PERL_ANYEVENT_MAX_SIGNAL_LATENCY}> or
C<$AnyEvent::MAX_SIGNAL_LATENCY> - see the L<ENVIRONMENT VARIABLES>
section for details.

All these problems can be avoided by installing the optional
L<Async::Interrupt> module, which works with most event loops. It will not

lib/AnyEvent/Debug.pm  view on Meta::CPAN

of connections are accepted on the port, and they will give you a very
primitive shell that simply executes every line you enter.

All commands will be executed "blockingly" with the socket C<select>ed for
output. For a less "blocking" interface see L<Coro::Debug>.

The commands will be executed in the C<AnyEvent::Debug::shell> package,
which currently has "help" and a few other commands, and can be freely
modified by all shells. Code is evaluated under C<use strict 'subs'>.

Every shell has a logging context (C<$LOGGER>) that is attached to
C<$AnyEvent::Log::COLLECT>), which is especially useful to gether debug
and trace messages.

As a general programming guide, consider the beneficial aspects of
using more global (C<our>) variables than local ones (C<my>) in package
scope: Earlier all my modules tended to hide internal variables inside
C<my> variables, so users couldn't accidentally access them. Having
interactive access to your programs changed that: having internal
variables still in the global scope means you can debug them easier.

lib/AnyEvent/Debug.pm  view on Meta::CPAN


      my $logger = new AnyEvent::Log::Ctx
         log_cb => sub {
            syswrite $fh, shift;
            0
         };

      my $logger_guard = AnyEvent::Util::guard {
         $AnyEvent::Log::COLLECT->detach ($logger);
      };
      $AnyEvent::Log::COLLECT->attach ($logger);

      local $TRACE = 0;
      my $rw; $rw = AE::io $fh, 0, sub {
         my $len = sysread $fh, $rbuf, 1024, length $rbuf;

         $logger_guard if 0; # reference it

         if (defined $len ? $len == 0 : ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK)) {
            undef $rw;
         } else {

lib/AnyEvent/Impl/IOAsync.pm  view on Meta::CPAN

      handle => $_[0][0],
      $_[0][1] => 1,
   );
}

sub signal {
   my ($class, %arg) = @_;

   my $signal = $arg{signal};

   my $id = $LOOP->attach_signal ($arg{signal}, $arg{cb});
   bless [$signal, $id], "AnyEvent::Impl::IOAsync::signal"
}

sub AnyEvent::Impl::IOAsync::signal::DESTROY {
   $LOOP->detach_signal (@{ $_[0] });
}

our %pid_cb;

sub child {

lib/AnyEvent/Log.pm  view on Meta::CPAN


   # set default logging level to suppress anything below "notice"
   # i.e. enable logging at "notice" or above - the default is to
   # to not log anything at all.
   $AnyEvent::Log::FILTER->level ("notice");

   # set logging for the current package to errors and higher only
   AnyEvent::Log::ctx->level ("error");

   # enable logging for the current package, regardless of global logging level
   AnyEvent::Log::ctx->attach ($AnyEvent::Log::LOG);

   # enable debug logging for module some::mod and enable logging by default
   (AnyEvent::Log::ctx "some::mod")->level ("debug");
   (AnyEvent::Log::ctx "some::mod")->attach ($AnyEvent::Log::LOG);

   # send all critical and higher priority messages to syslog,
   # regardless of (most) other settings
   $AnyEvent::Log::COLLECT->attach (new AnyEvent::Log::Ctx
      level         => "critical",
      log_to_syslog => "user",
   );

=head1 DESCRIPTION

This module implements a relatively simple "logging framework". It doesn't
attempt to be "the" logging solution or even "a" logging solution for
AnyEvent - AnyEvent simply creates logging messages internally, and this
module more or less exposes the mechanism, with some extra spiff to allow

lib/AnyEvent/Log.pm  view on Meta::CPAN

For the first purpose, filtering, each context has a set of logging
levels, called the log level mask. Messages not in the set will be ignored
by this context (masked).

For logging, the context stores a formatting callback (which takes the
timestamp, context, level and string message and formats it in the way
it should be logged) and a logging callback (which is responsible for
actually logging the formatted message and telling C<AnyEvent::Log>
whether it has consumed the message, or whether it should be propagated).

For propagation, a context can have any number of attached I<slave
contexts>. Any message that is neither masked by the logging mask nor
masked by the logging callback returning true will be passed to all slave
contexts.

Each call to a logging function will log the message at most once per
context, so it does not matter (much) if there are cycles or if the
message can arrive at the same context via multiple paths.

=head2 DEFAULTS

lib/AnyEvent/Log.pm  view on Meta::CPAN


Since perl packages form only an approximate hierarchy, this slave
context can of course be removed.

All other (anonymous) contexts have no slaves and an empty title by
default.

When the module is loaded it creates the C<$AnyEvent::Log::LOG> logging
context that simply logs everything via C<warn>, without propagating
anything anywhere by default.  The purpose of this context is to provide
a convenient place to override the global logging target or to attach
additional log targets. It's not meant for filtering.

It then creates the C<$AnyEvent::Log::FILTER> context whose
purpose is to suppress all messages with priority higher
than C<$ENV{PERL_ANYEVENT_VERBOSE}>. It then attached the
C<$AnyEvent::Log::LOG> context to it. The purpose of the filter context
is to simply provide filtering according to some global log level.

Finally it creates the top-level package context C<$AnyEvent::Log::COLLECT>
and attaches the C<$AnyEvent::Log::FILTER> context to it, but otherwise
leaves it at default config. Its purpose is simply to collect all log
messages system-wide.

The hierarchy is then:

   any package, eventually -> $COLLECT -> $FILTER -> $LOG

The effect of all this is that log messages, by default, wander up to the
C<$AnyEvent::Log::COLLECT> context where all messages normally end up,
from there to C<$AnyEvent::Log::FILTER> where log messages with lower
priority then C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered out and then
to the C<$AnyEvent::Log::LOG> context to be passed to C<warn>.

This makes it easy to set a global logging level (by modifying $FILTER),
but still allow other contexts to send, for example, their debug and trace
messages to the $LOG target despite the global logging level, or to attach
additional log targets that log messages, regardless of the global logging
level.

It also makes it easy to modify the default warn-logger ($LOG) to
something that logs to a file, or to attach additional logging targets
(such as loggign to a file) by attaching it to $FILTER.

=head2 CREATING/FINDING/DESTROYING CONTEXTS

=over 4

=item $ctx = AnyEvent::Log::ctx [$pkg]

This function creates or returns a logging context (which is an object).

If a package name is given, then the context for that package is

lib/AnyEvent/Log.pm  view on Meta::CPAN


our $ORIG_VERBOSE = $AnyEvent::VERBOSE;
$AnyEvent::VERBOSE = 9;

sub reset {
   # hard to kill complex data structures
   # we "recreate" all package loggers and reset the hierarchy
   while (my ($k, $v) = each %CTX) {
      @$v = ($k, (1 << 10) - 1 - 1, { });

      $v->attach ($k =~ /^(.+)::/ ? $CTX{$1} : $AnyEvent::Log::COLLECT);
   }

   @$_ = ($_->[0], (1 << 10) - 1 - 1)
      for $LOG, $FILTER, $COLLECT;

   #$LOG->slaves;
   $LOG->title ('$AnyEvent::Log::LOG');
   $LOG->log_to_warn;

   $FILTER->slaves ($LOG);

lib/AnyEvent/Log.pm  view on Meta::CPAN


sub cap {
   my $ctx = shift;
   $ctx->[5] = &_lvl;
}

=back

=head3 SLAVE CONTEXTS

The following methods attach and detach another logging context to a
logging context.

Log messages are propagated to all slave contexts, unless the logging
callback consumes the message.

=over 4

=item $ctx->attach ($ctx2[, $ctx3...])

Attaches the given contexts as slaves to this context. It is not an error
to add a context twice (the second add will be ignored).

A context can be specified either as package name or as a context object.

=item $ctx->detach ($ctx2[, $ctx3...])

Removes the given slaves from this context - it's not an error to attempt
to remove a context that hasn't been added.

A context can be specified either as package name or as a context object.

=item $ctx->slaves ($ctx2[, $ctx3...])

Replaces all slaves attached to this context by the ones given.

=cut

sub attach {
   my $ctx = shift;

   $ctx->[2]{$_+0} = $_
      for map { AnyEvent::Log::ctx $_ } @_;
   AnyEvent::Log::_reassess;
}

sub detach {
   my $ctx = shift;

   delete $ctx->[2]{$_+0}
      for map { AnyEvent::Log::ctx $_ } @_;
   AnyEvent::Log::_reassess;
}

sub slaves {
   undef $_[0][2];
   &attach;
   AnyEvent::Log::_reassess;
}

=back

=head3 LOG TARGETS

The following methods configure how the logging context actually does
the logging (which consists of formatting the message and printing it or
whatever it wants to do with it).

lib/AnyEvent/Log.pm  view on Meta::CPAN


=item C<collect>, C<filter>, C<log>

Correspond to the three predefined C<$AnyEvent::Log::COLLECT>,
C<AnyEvent::Log::FILTER> and C<$AnyEvent::Log::LOG> contexts.

=item C<%name>

Context names starting with a C<%> are anonymous contexts created when the
name is first mentioned. The difference to package contexts is that by
default they have no attached slaves.

This makes it possible to create new log contexts that can be refered to
multiple times by name within the same log specification.

=item a perl package name

Any other string references the logging context associated with the given
Perl C<package>. In the unlikely case where you want to specify a package
context that matches on of the other context name forms, you can add a
C<::> to the package name to force interpretation as a package.

lib/AnyEvent/Log.pm  view on Meta::CPAN

to the most recent C<only>, C<except> or C<level> directive. By default,
specifying a logging level enables that and any higher priority messages.

=item C<+>I<context>

Attaches the named context as slave to the context.

=item C<+>

A lone C<+> detaches all contexts, i.e. clears the slave list from the
context. Anonymous (C<%name>) contexts have no attached slaves by default,
but package contexts have the parent context as slave by default.

Example: log messages from My::Module to a file, do not send them to the
default log collector.

   My::Module=+,file=/tmp/mymodulelog

=back

Any character can be escaped by prefixing it with a C<\> (backslash), as

lib/AnyEvent/Log.pm  view on Meta::CPAN

      my $level = "level";

      while (/\G((?:[^,:[:space:]]+|::|\\.)+)/gc) {
         for ("$1") {
            if ($_ eq "stderr"               ) { $ctx->log_to_warn;
            } elsif (/^file=(.+)/            ) { $ctx->log_to_file ("$1");
            } elsif (/^path=(.+)/            ) { $ctx->log_to_path ("$1");
            } elsif (/^syslog(?:=(.*))?/     ) { require Sys::Syslog; $ctx->log_to_syslog ("$1");
            } elsif ($_ eq "nolog"           ) { $ctx->log_cb (undef);
            } elsif (/^cap=(.+)/             ) { $ctx->cap ("$1");
            } elsif (/^\+(.+)$/              ) { $ctx->attach ($pkg->("$1"));
            } elsif ($_ eq "+"               ) { $ctx->slaves;
            } elsif ($_ eq "off" or $_ eq "0") { $ctx->level (0);
            } elsif ($_ eq "all"             ) { $ctx->level ("all");
            } elsif ($_ eq "level"           ) { $ctx->level ("all"); $level = "level";
            } elsif ($_ eq "only"            ) { $ctx->level ("off"); $level = "enable";
            } elsif ($_ eq "except"          ) { $ctx->level ("all"); $level = "disable";
            } elsif (/^\d$/                  ) { $ctx->$level ($_);
            } elsif (exists $STR2LEVEL{$_}   ) { $ctx->$level ($_);
            } else                             { die "PERL_ANYEVENT_LOG ($spec): parse error at '$_'\n";
            }

lib/AnyEvent/Log.pm  view on Meta::CPAN


This is affected by the global logging level.

   $AnyEvent::Log::LOG->log_to_file ($path);

   PERL_ANYEVENT_LOG=log=file=/some/path

=item Write all messages with priority C<error> and higher to a file.

This writes them only when the global logging level allows it, because
it is attached to the default context which is invoked I<after> global
filtering.

   $AnyEvent::Log::FILTER->attach (
      new AnyEvent::Log::Ctx log_to_file => $path);

   PERL_ANYEVENT_LOG=filter=+%filelogger:%filelogger=file=/some/path

This writes them regardless of the global logging level, because it is
attached to the toplevel context, which receives all messages I<before>
the global filtering.

   $AnyEvent::Log::COLLECT->attach (
      new AnyEvent::Log::Ctx log_to_file => $path);

   PERL_ANYEVENT_LOG=%filelogger=file=/some/path:collect=+%filelogger

In both cases, messages are still written to STDERR.

=item Additionally log all messages with C<warn> and higher priority to
C<syslog>, but cap at C<error>.

This logs all messages to the default log target, but also logs messages
with priority C<warn> or higher (and not filtered otherwise) to syslog
facility C<user>. Messages with priority higher than C<error> will be
logged with level C<error>.

   $AnyEvent::Log::LOG->attach (
      new AnyEvent::Log::Ctx
         level  => "warn",
         cap    => "error",
         syslog => "user",
   );

   PERL_ANYEVENT_LOG=log=+%syslog:%syslog=warn,cap=error,syslog

=item Write trace messages (only) from L<AnyEvent::Debug> to the default logging target(s).

Attach the C<$AnyEvent::Log::LOG> context to the C<AnyEvent::Debug>
context - this simply circumvents the global filtering for trace messages.

   my $debug = AnyEvent::Debug->AnyEvent::Log::ctx;
   $debug->attach ($AnyEvent::Log::LOG);

   PERL_ANYEVENT_LOG=AnyEvent::Debug=+log

This of course works for any package, not just L<AnyEvent::Debug>, but
assumes the log level for AnyEvent::Debug hasn't been changed from the
default.

=back

=head1 ASYNCHRONOUS DISK I/O



( run in 0.640 second using v1.01-cache-2.11-cpan-df04353d9ac )