1AnyEvent::Impl::POE(3)User Contributed Perl DocumentationAnyEvent::Impl::POE(3)
2
3
4

NAME

6       AnyEvent::Impl::POE - AnyEvent adaptor for POE
7

SYNOPSIS

9          use AnyEvent;
10          use POE;
11
12          # this module gets loaded automatically as required
13

DESCRIPTION

15       This module provides transparent support for AnyEvent. You don't have
16       to do anything to make POE work with AnyEvent except by loading POE
17       before creating the first AnyEvent watcher. There are some cases where
18       POE will issue spurious (and non-suppressible) warnings. These can be
19       avoided by loading AnyEvent::Impl::POE before loading any other modules
20       using POE and AnyEvent, i.e. in your main program.
21
22       AnyEvent::Impl::POE will output some spurious message how to work
23       around POE's spurious messages when it detects these cases.
24
25       Unfortunately, POE isn't generic enough to implement a fully working
26       AnyEvent backend: POE is too badly designed, too badly documented and
27       too badly implemented.
28
29       Here are the details, and what it means to you if you want to be
30       interoperable with POE:
31
32       Weird messages
33           If you only use "run_one_timeslice" (as AnyEvent has to for its
34           condition variables), POE will print an ugly, unsuppressible,
35           message at program exit:
36
37              Sessions were started, but POE::Kernel's run() method was never...
38
39           The message is correct, the question is why POE prints it in the
40           first place in a correct program (this is not a singular case
41           though).
42
43           AnyEvent consequently patches the POE kernel so it thinks it
44           already ran. Other workarounds, even the one cited in the POE
45           documentation itself, have serious side effects, such as throwing
46           away events.
47
48           The author of POE verified that this is indeed true, and has no
49           plans to change this.
50
51           POE has other weird messages, and sometimes weird behaviour, for
52           example, it doesn't support overloaded code references as callbacks
53           for no apparent reason.
54
55       One POE session per Event
56           AnyEvent has to create one POE::Session per event watcher, which is
57           immensely slow and makes watchers very large. The reason for this
58           is lacking lifetime management (mostly undocumented, too). Without
59           one session/watcher it is not possible to easily keep the kernel
60           from running endlessly.
61
62           This is not just a problem with the way AnyEvent has to interact
63           with POE, but is a principal issue with POEs lifetime management
64           (namely that stopping the kernel stops sessions, but AnyEvent has
65           no control over who and when the kernel starts or stops w.r.t.
66           AnyEvent watcher creation/destruction).
67
68           From benchmark data it is not clear that session creation is that
69           costly, though - the real inefficiencies with POE seem to come from
70           other sources, such as event handling.
71
72       One watcher per fd/event combo
73           POE, of course, suffers from the same bug as Tk and some other
74           badly designed event models in that it doesn't support multiple
75           watchers per fd/poll combo. The workaround is the same as with Tk:
76           AnyEvent::Impl::POE creates a separate file descriptor to hand to
77           POE, which isn't fast and certainly not nice to your resources.
78
79           Of course, without the workaround, POE also prints ugly messages
80           again that say the program *might* be buggy.
81
82           While this is not good to performance, at least regarding speed,
83           with a modern Linux kernel, the overhead is actually quite small.
84
85       Timing deficiencies
86           POE manages to not have a function that returns the current time.
87           This is extremely problematic, as POE can use different time
88           functions, which can differ by more than a second - and user code
89           is left guessing which one is used.
90
91           In addition, most timer functions in POE want an absolute
92           timestamp, which is hard to create if all you have is a relative
93           time and no function to return the "current time".
94
95           And of course POE doesn't handle time jumps at all (not even when
96           using an event loop that happens to do that, such as EV, as it does
97           its own unoptimised timer management).
98
99           AnyEvent works around the unavailability of the current time using
100           relative timers exclusively, in the hope that POE gets it right at
101           least internally.
102
103       Lack of defined event ordering
104           POE cannot guarantee the order of callback invocation for timers,
105           and usually gets it wrong. That is, if you have two timers, one
106           timing out after another (all else being equal), the callbacks
107           might be called in reverse order.
108
109           How one manages to even implement stuff that way escapes me.
110
111       Child watchers
112           POE offers child watchers - which is a laudable thing, as few event
113           loops do. Unfortunately, they cannot even implement AnyEvent's
114           simple child watchers: they are not generic enough (the POE
115           implementation isn't even generic enough to let properly designed
116           back-end use their native child watcher instead - it insist on
117           doing it itself the broken way).
118
119           Unfortunately, POE's child handling is inherently racy: if the
120           child exits before the handler is created (because e.g. it crashes
121           or simply is quick about it), then current versions of POE (1.352)
122           will never invoke the child watcher, and there is nothing that can
123           be done about it. Older versions of POE only delayed in this case.
124           The reason is that POE first checks if the child has already
125           exited, and then installs the signal handler - aa classical race.
126
127           Your only hope is for the fork'ed process to not exit too quickly,
128           in which case everything happens to work.
129
130           Of course, whenever POE reaps an unrelated child it will also
131           output a message for it that you cannot suppress (which shouldn't
132           be too surprising at this point). Very professional.
133
134           As a workaround, AnyEvent::Impl::POE will take advantage of
135           undocumented behaviour in POE::Kernel to catch the status of all
136           child processes, but it cannot guarantee delivery.
137
138           How one manages to have such a glaring bug in an event loop after
139           ten years of development escapes me.
140
141           (There are more annoying bugs, for example, POE runs "waitpid"
142           unconditionally at finaliser time, so your program will hang until
143           all child processes have exited.)
144
145       Documentation quality
146           At the time of this writing, POE was in its tenth year. Still, its
147           documentation is extremely lacking, making it impossible to
148           implement stuff as trivial as AnyEvent watchers without having to
149           resort to undocumented behaviour or features.
150
151           For example, the POE::Kernel manpage has nine occurrences of the
152           word TODO with an explanation of whats missing. In general, the POE
153           man pages are littered with comments like "section not yet
154           written".
155
156           Some other gems:
157
158              This allows many object methods to also be package methods.
159
160           This is nice, but since it doesn't document which methods these
161           are, this is utterly useless information.
162
163              Terminal signals will kill sessions if they are not handled by a
164              "sig_handled"() call. The OS signals that usually kill or dump a
165              process are considered terminal in POE, but they never trigger a
166              coredump. These are: HUP, INT, QUIT and TERM.
167
168           Although AnyEvent calls "sig_handled", removing it has no apparent
169           effects on POE handling SIGINT.
170
171              refcount_increment SESSION_ID, COUNTER_NAME
172
173           Nowhere is explained which COUNTER_NAMEs are valid and which aren't
174           - not all scalars (or even strings) are valid counter names. Take
175           your guess, failure is of course completely silent. I found this
176           out the hard way, as the first name I came up with was silently
177           ignored.
178
179              get_next_event_time() returns the time the next event is due, in a form
180              compatible with the UNIX time() function.
181
182           And surely, one would hope that POE supports sub-second accuracy as
183           documented elsewhere, unlike the explanation above implies. Yet:
184
185              POE::Kernel timers support subsecond accuracy, but don’t expect too
186              much here. Perl is not the right language for realtime programming.
187
188           ... of course, Perl is not the right language to expect sub-second
189           accuracy - the manpage author must hate Perl to spread so much FUD
190           in so little space. The Deliantra game server logs with
191           100µs-accuracy because Perl is fast enough to require this, and is
192           still able to deliver map updates with little jitter at exactly the
193           right time. It does not, however, use POE.
194
195              Furthermore, since the Kernel keeps track of everything sessions do, it
196              knows when a session has run out of tasks to perform.
197
198           This is impossible - how does the kernel know that a session is no
199           longer watching for some (external) event (e.g. by some other
200           session)? It cannot, and therefore this is wrong - but you would be
201           hard pressed to find out how to work around this and tell the
202           kernel manually about such events.
203
204           It gets worse, though - the notion of "task" or "resource",
205           although used throughout the documentation, is not defined in a
206           usable way. For example, waiting for a timeout is considered to be
207           a task, waiting for a signal is not (a session that only waits for
208           a signal is considered finished and gets removed). The user is left
209           guessing when waiting for an event counts as task and when not (in
210           fact, the issue with signals is mentioned in passing in a section
211           about child watchers and directly contradicts earlier parts in that
212           document).
213
214           One could go on endlessly - ten years, no usable documentation.
215
216           It is likely that differences between documentation, or the one or
217           two things I had to guess, cause unanticipated problems with this
218           adaptor.
219
220       Fragile and inconsistent API
221           The POE API is extremely inconsistent - sometimes you have to pass
222           a session argument, sometimes it gets ignored, sometimes a session-
223           specific method must not use a session argument.
224
225           Error handling is sub-standard as well: even for programming
226           mistakes, POE does not "croak" but, in most cases, just sets $! or
227           simply does nothing at all, leading to fragile programs.
228
229           Sometimes registering a handler uses the "eventname, parameter"
230           ordering (timeouts), sometimes it is "parameter, eventname"
231           (signals). There is little consistency overall.
232
233       Lack of knowledge
234              The IO::Poll event loop provides an alternative that theoretically
235              scales better than select().
236
237           The IO::Poll "event loop" (who in his right mind would call that an
238           event loop) of course scales about identically (sometimes it is a
239           bit faster, sometimes a bit slower) to select in theory, and also
240           in practise, of course, as both are O(n) in the number of file
241           descriptors, which is rather bad.
242
243           This is just one place where it gets obvious how little the author
244           of the POE manpage understands.
245
246       No idle events
247           The POE-recommended workaround to this is apparently to use "fork".
248           Consequently, idle watchers will have to be emulated by AnyEvent.
249
250       Questionable maintainer behaviour
251           The author of POE is known to fabricate statements and post these
252           to public mailinglists - apparently, spreading FUD about competing
253           (in his eyes) projects or their maintainers is acceptable to him.
254
255           This has (I believe) zero effects on the quality or usefulness of
256           his code, but it does completely undermine his trustworthyness - so
257           don't blindly believe anything he says, he might have just made it
258           up to suit his needs (benchmark results, the names of my ten wifes,
259           the length of my penis, etc. etc.). When in doubt, double-check -
260           not just him, anybody actually.
261
262           Example:
263           <http://www.nntp.perl.org/group/perl.perl5.porters/2012/01/msg182141.html>.
264           I challenged him in that thread to provide evidence for his
265           statement by giving at least two examples, but of course since he
266           just made it up, he couldn't provide any evidence.
267
268       On the good side, AnyEvent allows you to write your modules in a 100%
269       POE-compatible way (bug-for-bug compatible even), without forcing your
270       module to use POE - it is still open to better event models, of which
271       there are plenty.
272
273       Oh, and one other positive thing:
274
275          RUNNING_IN_HELL
276
277       POE knows about the nature of the beast!
278

SEE ALSO

280       AnyEvent, POE.
281

AUTHOR

283        Marc Lehmann <schmorp@schmorp.de>
284        http://anyevent.schmorp.de
285
286
287
288perl v5.36.0                      2022-07-22            AnyEvent::Impl::POE(3)
Impressum