Provided by: libanyevent-perl_7.170-2build6_amd64 bug

NAME

       AnyEvent::Impl::POE - AnyEvent adaptor for POE

SYNOPSIS

          use AnyEvent;
          use POE;

          # this module gets loaded automatically as required

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:

       Weird messages
           If  you only use "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.

       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.

       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.

       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 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.

       Lack of defined event ordering
           POE cannot guarantee the order of callback invocation for timers, and usually gets it wrong. That is,
           if  you  have two timers, one timing out after another (all else being equal), the callbacks might be
           called in reverse order.

           How one manages to even implement stuff that way escapes me.

       Child watchers
           POE offers child watchers - which is a laudable thing, as few event  loops  do.  Unfortunately,  they
           cannot  even  implement  AnyEvent's  simple  child  watchers:  they  are  not generic enough (the POE
           implementation isn't even generic enough to let properly designed back-end  use  their  native  child
           watcher instead - it insist on doing it itself the broken way).

           Unfortunately,  POE's  child  handling  is  inherently racy: if the child exits before the handler is
           created (because e.g. it crashes or simply is quick about it), then current versions of  POE  (1.352)
           will  never  invoke the child watcher, and there is nothing that can be done about it. Older versions
           of POE only delayed in this case. The reason is that POE  first  checks  if  the  child  has  already
           exited, and then installs the signal handler - aa classical race.

           Your  only  hope is for the fork'ed process to not exit too quickly, in which case everything happens
           to work.

           Of course, whenever POE reaps an unrelated child it will also output a message for it that you cannot
           suppress (which shouldn't be too surprising at this point). Very professional.

           As a workaround, AnyEvent::Impl::POE will take advantage of undocumented behaviour in POE::Kernel  to
           catch the status of all child processes, but it cannot guarantee delivery.

           How  one  manages  to have such a glaring bug in an event loop after ten years of development escapes
           me.

           (There are more annoying bugs, for example, POE runs "waitpid" unconditionally at finaliser time,  so
           your program will hang until all child processes have exited.)

       Documentation quality
           At  the  time  of  this  writing,  POE  was  in its tenth year. Still, its documentation is extremely
           lacking, making it impossible to implement stuff as trivial as AnyEvent watchers  without  having  to
           resort to undocumented behaviour or features.

           For  example,  the  POE::Kernel  manpage has nine occurrences of the word TODO with an explanation of
           whats missing. In general, the POE man pages  are  littered  with  comments  like  "section  not  yet
           written".

           Some other gems:

              This allows many object methods to also be package methods.

           This  is  nice,  but  since  it  doesn't  document  which  methods these are, this is utterly useless
           information.

              Terminal signals will kill sessions if they are not handled by a
              "sig_handled"() call. The OS signals that usually kill or dump a
              process are considered terminal in POE, but they never trigger a
              coredump. These are: HUP, INT, QUIT and TERM.

           Although AnyEvent calls "sig_handled", removing it has no apparent effects on POE handling SIGINT.

              refcount_increment SESSION_ID, COUNTER_NAME

           Nowhere is explained which COUNTER_NAMEs are valid and which  aren't  -  not  all  scalars  (or  even
           strings)  are  valid  counter names. Take your guess, failure is of course completely silent. I found
           this out the hard way, as the first name I came up with was silently ignored.

              get_next_event_time() returns the time the next event is due, in a form
              compatible with the UNIX time() function.

           And surely, one would hope that POE supports sub-second accuracy as documented elsewhere, unlike  the
           explanation above implies. Yet:

              POE::Kernel timers support subsecond accuracy, but don’t expect too
              much here. Perl is not the right language for realtime programming.

           ... of course, Perl is not the right language to expect sub-second accuracy - the manpage author must
           hate  Perl  to  spread  so  much  FUD  in  so  little  space.  The  Deliantra  game  server logs with
           100µs-accuracy because Perl is fast enough to require this, and is still able to deliver map  updates
           with little jitter at exactly the right time. It does not, however, use POE.

              Furthermore, since the Kernel keeps track of everything sessions do, it
              knows when a session has run out of tasks to perform.

           This  is  impossible  -  how  does  the  kernel  know  that  a session is no longer watching for some
           (external) event (e.g. by some other session)? It cannot, and therefore this is wrong - but you would
           be hard pressed to find out how to work around this and tell the kernel manually about such events.

           It gets  worse,  though  -  the  notion  of  "task"  or  "resource",  although  used  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.

       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 "croak"  but,  in
           most cases, just sets $! 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.

       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.

       No idle events
           The POE-recommended workaround to this is apparently to use "fork". Consequently, idle watchers  will
           have to be emulated by AnyEvent.

       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:  <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.

       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!

SEE ALSO

       AnyEvent, POE.

AUTHOR

        Marc Lehmann <schmorp@schmorp.de>
        http://anyevent.schmorp.de

perl v5.38.2                                       2024-03-31                           AnyEvent::Impl::POE(3pm)