AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Impl/POE.pm view on Meta::CPAN
throughout the documentation, is not defined in a usable way. For example,
waiting for a timeout is considered to be a task, waiting for a signal is
not (a session that only waits for a signal is considered finished and
gets removed). The user is left guessing when waiting for an event counts
as task and when not (in fact, the issue with signals is mentioned in
passing in a section about child watchers and directly contradicts earlier
parts in that document).
One could go on endlessly - ten years, no usable documentation.
It is likely that differences between documentation, or the one or two
things I had to guess, cause unanticipated problems with this adaptor.
=item Fragile and inconsistent API
The POE API is extremely inconsistent - sometimes you have to pass a
session argument, sometimes it gets ignored, sometimes a session-specific
method must not use a session argument.
Error handling is sub-standard as well: even for programming mistakes,
POE does not C<croak> but, in most cases, just sets C<$!> or simply does
nothing at all, leading to fragile programs.
Sometimes registering a handler uses the "eventname, parameter" ordering
(timeouts), sometimes it is "parameter, eventname" (signals). There is
little consistency overall.
=item Lack of knowledge
The IO::Poll event loop provides an alternative that theoretically
scales better than select().
The IO::Poll "event loop" (who in his right mind would call that an event
loop) of course scales about identically (sometimes it is a bit faster,
sometimes a bit slower) to select in theory, and also in practise, of
course, as both are O(n) in the number of file descriptors, which is
rather bad.
This is just one place where it gets obvious how little the author of the
POE manpage understands.
=item No idle events
The POE-recommended workaround to this is apparently to use
C<fork>. Consequently, idle watchers will have to be emulated by AnyEvent.
=item Questionable maintainer behaviour
The author of POE is known to fabricate statements and post these to
public mailinglists - apparently, spreading FUD about competing (in his
eyes) projects or their maintainers is acceptable to him.
This has (I believe) zero effects on the quality or usefulness of his
code, but it does completely undermine his trustworthyness - so don't
blindly believe anything he says, he might have just made it up to suit
his needs (benchmark results, the names of my ten wifes, the length of my
penis, etc. etc.). When in doubt, double-check - not just him, anybody
actually.
Example: L<http://www.nntp.perl.org/group/perl.perl5.porters/2012/01/msg182141.html>.
I challenged him in that thread to provide evidence for his statement by giving at
least two examples, but of course since he just made it up, he couldn't provide any evidence.
=back
On the good side, AnyEvent allows you to write your modules in a 100%
POE-compatible way (bug-for-bug compatible even), without forcing your
module to use POE - it is still open to better event models, of which
there are plenty.
Oh, and one other positive thing:
RUNNING_IN_HELL
POE knows about the nature of the beast!
=cut
package AnyEvent::Impl::POE;
use AnyEvent (); BEGIN { AnyEvent::common_sense }
use POE;
# suppress an idiotic warning inside POE
${ POE::Kernel->new->[POE::Kernel::KR_RUN] } |= POE::Kernel::KR_RUN_CALLED;
sub io {
my ($class, %arg) = @_;
# POE itself might do the right thing, but some POE backends don't,
# so do the safe thing, it's not as if this will slow us down
# any further *g*
my ($fh, $pee) = AnyEvent::_dupfh $arg{poll}, $arg{fh}, "select_read", "select_write";
my $cb = delete $arg{cb}; my $cb = sub { &$cb }; # POE doesn't like callable objects
my $session = POE::Session->create (
inline_states => {
_start => sub { $_[KERNEL]->$pee ($fh => "ready") },
ready => sub { $cb->() },
stop => sub { $_[KERNEL]->$pee ($fh) },
},
);
bless \\$session, "AnyEvent::Impl::POE"
}
sub timer {
my ($class, %arg) = @_;
my $after = delete $arg{after};
my $ival = delete $arg{interval};
my $cb = delete $arg{cb}; my $cb = sub { &$cb }; # POE doesn't like callable objects
my $session = POE::Session->create (
inline_states => {
_start => sub {
$_[KERNEL]->delay_set (timeout => $after);
},
timeout => $ival ? sub { $_[KERNEL]->delay_set (timeout => $ival); $cb->() } : $cb,
stop => sub {
$_[KERNEL]->alarm_remove_all;
( run in 1.777 second using v1.01-cache-2.11-cpan-5b529ec07f3 )