AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Impl/POE.pm view on Meta::CPAN
=head1 NAME
AnyEvent::Impl::POE - AnyEvent adaptor for POE
=encoding utf-8
=head1 SYNOPSIS
use AnyEvent;
use POE;
# this module gets loaded automatically as required
=head1 DESCRIPTION
This module provides transparent support for AnyEvent. You don't have to
do anything to make POE work with AnyEvent except by loading POE before
creating the first AnyEvent watcher. There are some cases where POE will
issue spurious (and non-suppressible) warnings. These can be avoided by
loading AnyEvent::Impl::POE before loading any other modules using POE and
AnyEvent, i.e. in your main program.
AnyEvent::Impl::POE will output some spurious message how to work around
POE's spurious messages when it detects these cases.
Unfortunately, POE isn't generic enough to implement a fully working
AnyEvent backend: POE is too badly designed, too badly documented and too
badly implemented.
Here are the details, and what it means to you if you want to be
interoperable with POE:
=over 4
=item Weird messages
If you only use C<run_one_timeslice> (as AnyEvent has to for its
condition variables), POE will print an ugly, unsuppressible, message at
program exit:
Sessions were started, but POE::Kernel's run() method was never...
The message is correct, the question is why POE prints it in the first
place in a correct program (this is not a singular case though).
AnyEvent consequently patches the POE kernel so it thinks it already
ran. Other workarounds, even the one cited in the POE documentation
itself, have serious side effects, such as throwing away events.
The author of POE verified that this is indeed true, and has no plans to
change this.
POE has other weird messages, and sometimes weird behaviour, for example,
it doesn't support overloaded code references as callbacks for no apparent
reason.
=item One POE session per Event
AnyEvent has to create one POE::Session per event watcher, which is
immensely slow and makes watchers very large. The reason for this is
lacking lifetime management (mostly undocumented, too). Without one
session/watcher it is not possible to easily keep the kernel from running
endlessly.
This is not just a problem with the way AnyEvent has to interact with
POE, but is a principal issue with POEs lifetime management (namely
that stopping the kernel stops sessions, but AnyEvent has no control
over who and when the kernel starts or stops w.r.t. AnyEvent watcher
creation/destruction).
From benchmark data it is not clear that session creation is that costly,
though - the real inefficiencies with POE seem to come from other sources,
such as event handling.
=item One watcher per fd/event combo
POE, of course, suffers from the same bug as Tk and some other badly
designed event models in that it doesn't support multiple watchers per
fd/poll combo. The workaround is the same as with Tk: AnyEvent::Impl::POE
creates a separate file descriptor to hand to POE, which isn't fast and
certainly not nice to your resources.
Of course, without the workaround, POE also prints ugly messages again
that say the program *might* be buggy.
While this is not good to performance, at least regarding speed, with a
modern Linux kernel, the overhead is actually quite small.
=item Timing deficiencies
POE manages to not have a function that returns the current time. This is
extremely problematic, as POE can use different time functions, which can
differ by more than a second - and user code is left guessing which one is
used.
In addition, most timer functions in POE want an absolute timestamp, which
is hard to create if all you have is a relative time and no function to
return the "current time".
And of course POE doesn't handle time jumps at all (not even when using
an event loop that happens to do that, such as L<EV>, as it does its own
unoptimised timer management).
AnyEvent works around the unavailability of the current time using
relative timers exclusively, in the hope that POE gets it right at least
internally.
=item Lack of defined event ordering
( run in 0.591 second using v1.01-cache-2.11-cpan-39bf76dae61 )