AnyEvent
view release on metacpan or search on metacpan
my $cv = AnyEvent->condvar;
my %result;
$cv->begin (sub { shift->send (\%result) });
for my $host (@list_of_hosts) {
$cv->begin;
ping_host_then_call_callback $host, sub {
$result{$host} = ...;
$cv->end;
};
}
$cv->end;
...
my $results = $cv->recv;
This code fragment supposedly pings a number of hosts and calls
"send" after results for all then have have been gathered - in any
order. To achieve this, the code issues a call to "begin" when it
starts each ping request and calls "end" when it has received some
result for it. Since "begin" and "end" only maintain a counter, the
order in which results arrive is not relevant.
There is an additional bracketing call to "begin" and "end" outside
the loop, which serves two important purposes: first, it sets the
callback to be called once the counter reaches 0, and second, it
ensures that "send" is called even when "no" hosts are being pinged
(the loop doesn't execute once).
This is the general pattern when you "fan out" into multiple (but
potentially zero) subrequests: use an outer "begin"/"end" pair to
set the callback and ensure "end" is called at least once, and then,
for each subrequest you start, call "begin" and for each subrequest
you finish, call "end".
METHODS FOR CONSUMERS
These methods should only be used by the consuming side, i.e. the code
awaits the condition.
$cv->recv
Wait (blocking if necessary) until the "->send" or "->croak" methods
have been called on $cv, while servicing other watchers normally.
You can only wait once on a condition - additional calls are valid
but will return immediately.
If an error condition has been set by calling "->croak", then this
function will call "croak".
In list context, all parameters passed to "send" will be returned,
in scalar context only the first one will be returned.
Note that doing a blocking wait in a callback is not supported by
any event loop, that is, recursive invocation of a blocking "->recv"
is not allowed and the "recv" call will "croak" if such a condition
is detected. This requirement can be dropped by relying on
Coro::AnyEvent , which allows you to do a blocking "->recv" from any
thread that doesn't run the event loop itself. Coro::AnyEvent is
loaded automatically when Coro is used with AnyEvent, so code does
not need to do anything special to take advantage of that: any code
that would normally block your program because it calls "recv", be
executed in an "async" thread instead without blocking other
threads.
Not all event models support a blocking wait - some die in that case
(programs might want to do that to stay interactive), so *if you are
using this from a module, never require a blocking wait*. Instead,
let the caller decide whether the call will block or not (for
example, by coupling condition variables with some kind of request
results and supporting callbacks so the caller knows that getting
the result will not block, while still supporting blocking waits if
the caller so desires).
You can ensure that "->recv" never blocks by setting a callback and
only calling "->recv" from within that callback (or at a later
time). This will work even when the event loop does not support
blocking waits otherwise.
$bool = $cv->ready
Returns true when the condition is "true", i.e. whether "send" or
"croak" have been called.
$cb = $cv->cb ($cb->($cv))
This is a mutator function that returns the callback set (or "undef"
if not) and optionally replaces it before doing so.
The callback will be called when the condition becomes "true", i.e.
when "send" or "croak" are called, with the only argument being the
condition variable itself. If the condition is already true, the
callback is called immediately when it is set. Calling "recv" inside
the callback or at any later time is guaranteed not to block.
Additionally, when the callback is invoked, it is also removed from
the condvar (reset to "undef"), so the condvar does not keep a
reference to the callback after invocation.
SUPPORTED EVENT LOOPS/BACKENDS
The following backend classes are part of the AnyEvent distribution
(every class has its own manpage):
Backends that are autoprobed when no other event loop can be found.
EV is the preferred backend when no other event loop seems to be in
use. If EV is not installed, then AnyEvent will fall back to its own
pure-perl implementation, which is available everywhere as it comes
with AnyEvent itself.
AnyEvent::Impl::EV based on EV (interface to libev, best choice).
AnyEvent::Impl::Perl pure-perl AnyEvent::Loop, fast and portable.
Backends that are transparently being picked up when they are used.
These will be used if they are already loaded when the first watcher
is created, in which case it is assumed that the application is
using them. This means that AnyEvent will automatically pick the
right backend when the main program loads an event module before
anything starts to create watchers. Nothing special needs to be done
by the main program.
AnyEvent::Impl::Event based on Event, very stable, few glitches.
AnyEvent::Impl::Glib based on Glib, slow but very stable.
AnyEvent::Impl::Tk based on Tk, very broken.
AnyEvent::Impl::UV based on UV, innovated square wheels.
AnyEvent::Impl::EventLib based on Event::Lib, leaks memory and worse.
AnyEvent::Impl::POE based on POE, very slow, some limitations.
The guard module, when used, will be used to implement
"AnyEvent::Util::guard". This speeds up guards considerably (and
uses a lot less memory), but otherwise doesn't affect guard
operation much. It is purely used for performance.
JSON and JSON::XS
One of these modules is required when you want to read or write JSON
data via AnyEvent::Handle. JSON is also written in pure-perl, but
can take advantage of the ultra-high-speed JSON::XS module when it
is installed.
Net::SSLeay
Implementing TLS/SSL in Perl is certainly interesting, but not very
worthwhile: If this module is installed, then AnyEvent::Handle (with
the help of AnyEvent::TLS), gains the ability to do TLS/SSL.
Time::HiRes
This module is part of perl since release 5.008. It will be used
when the chosen event library does not come with a timing source of
its own. The pure-perl event loop (AnyEvent::Loop) will additionally
load it to try to use a monotonic clock for timing stability.
AnyEvent::AIO (and IO::AIO)
The default implementation of AnyEvent::IO is to do I/O
synchronously, stopping programs while they access the disk, which
is fine for a lot of programs.
Installing AnyEvent::AIO (and its IO::AIO dependency) makes it
switch to a true asynchronous implementation, so event processing
can continue even while waiting for disk I/O.
FORK
Most event libraries are not fork-safe. The ones who are usually are
because they rely on inefficient but fork-safe "select" or "poll" calls
- higher performance APIs such as BSD's kqueue or the dreaded Linux
epoll are usually badly thought-out hacks that are incompatible with
fork in one way or another. Only EV is fully fork-aware and ensures that
you continue event-processing in both parent and child (or both, if you
know what you are doing).
This means that, in general, you cannot fork and do event processing in
the child if the event library was initialised before the fork (which
usually happens when the first AnyEvent watcher is created, or the
library is loaded).
If you have to fork, you must either do so *before* creating your first
watcher OR you must not use AnyEvent at all in the child OR you must do
something completely out of the scope of AnyEvent (see below).
The problem of doing event processing in the parent *and* the child is
much more complicated: even for backends that *are* fork-aware or
fork-safe, their behaviour is not usually what you want: fork clones all
watchers, that means all timers, I/O watchers etc. are active in both
parent and child, which is almost never what you want. Using "exec" to
start worker children from some kind of manage prrocess is usually
preferred, because it is much easier and cleaner, at the expense of
having to have another binary.
In addition to logical problems with fork, there are also implementation
problems. For example, on POSIX systems, you cannot fork at all in Perl
code if a thread (I am talking of pthreads here) was ever created in the
process, and this is just the tip of the iceberg. In general, using fork
from Perl is difficult, and attempting to use fork without an exec to
implement some kind of parallel processing is almost certainly doomed.
To safely fork and exec, you should use a module such as Proc::FastSpawn
that let's you safely fork and exec new processes.
If you want to do multiprocessing using processes, you can look at the
AnyEvent::Fork module (and some related modules such as
AnyEvent::Fork::RPC, AnyEvent::Fork::Pool and AnyEvent::Fork::Remote).
This module allows you to safely create subprocesses without any
limitations - you can use X11 toolkits or AnyEvent in the children
created by AnyEvent::Fork safely and without any special precautions.
SECURITY CONSIDERATIONS
AnyEvent can be forced to load any event model via
$ENV{PERL_ANYEVENT_MODEL}. While this cannot (to my knowledge) be used
to execute arbitrary code or directly gain access, it can easily be used
to make the program hang or malfunction in subtle ways, as AnyEvent
watchers will not be active when the program uses a different event
model than specified in the variable.
You can make AnyEvent completely ignore this variable by deleting it
before the first watcher gets created, e.g. with a "BEGIN" block:
BEGIN { delete $ENV{PERL_ANYEVENT_MODEL} }
use AnyEvent;
Similar considerations apply to $ENV{PERL_ANYEVENT_VERBOSE}, as that can
be used to probe what backend is used and gain other information (which
is probably even less useful to an attacker than PERL_ANYEVENT_MODEL),
and $ENV{PERL_ANYEVENT_STRICT}.
Note that AnyEvent will remove *all* environment variables starting with
"PERL_ANYEVENT_" from %ENV when it is loaded while taint mode is
enabled.
BUGS
Perl 5.8 has numerous memleaks that sometimes hit this module and are
hard to work around. If you suffer from memleaks, first upgrade to Perl
5.10 and check wether the leaks still show up. (Perl 5.10.0 has other
annoying memleaks, such as leaking on "map" and "grep" but it is usually
not as pronounced).
SEE ALSO
Tutorial/Introduction: AnyEvent::Intro.
FAQ: AnyEvent::FAQ.
Utility functions: AnyEvent::Util (misc. grab-bag), AnyEvent::Log
(simply logging).
Development/Debugging: AnyEvent::Strict (stricter checking),
AnyEvent::Debug (interactive shell, watcher tracing).
Supported event modules: AnyEvent::Loop, EV, EV::Glib, Glib::EV, Event,
Glib::Event, Glib, Tk, Event::Lib, Qt, POE, FLTK, Cocoa::EventLoop, UV.
Implementations: AnyEvent::Impl::EV, AnyEvent::Impl::Event,
( run in 2.454 seconds using v1.01-cache-2.11-cpan-2398b32b56e )