perl.loop http://www.nntp.perl.org/group/perl.loop/ ... Copyright 1998-2008 perl.org Mon, 13 Oct 2008 13:21:39 +0000 ask@perl.org Run-time failure by Jeff Boes I&#39;m upgrading an ancient (2004-era) server to the modern era:<br/><br/>2.6.18-92.1.6.el5 x86_64 x86_64 x86_64 GNU/Linux<br/>Perl 5.10<br/>Event.pm 1.1<br/><br/>One of my applications throws the following error once it&#39;s been running for a<br/>few minutes as a daemon:<br/><br/>Assertion (((pe_watcher*)wa)-&gt;flags &amp; 0x0008) || !wa-&gt;running failed: file<br/>&quot;c/queue.c&quot;<br/><br/>Help or pointers to info would be appreciated.<br/><br/>-- <br/>Jeffery Boes &lt;&gt;&lt;<br/>jeff@endpoint.com<br/> http://www.nntp.perl.org/group/perl.loop/2008/09/msg1124.html Wed, 10 Sep 2008 05:40:47 +0000 Re: non blocking issue ? by Isabelle Cabrera `Zidane Tribal a &eacute;crit :<br/>&gt; On 28/05/2008, Isabelle Cabrera &lt;isabelle.cabrera@inria.fr&gt; wrote:<br/>&gt; <br/>&gt;&gt; Hi,<br/>&gt;&gt;<br/>&gt;&gt; I have a problem using the Event module.<br/>&gt;&gt;<br/>&gt;&gt; My goal: I have several sentences that I need to parse. For a faster<br/>&gt;&gt; process, I have a dispatcher which sends the sentences to several hosts<br/>&gt;&gt; so that the processes are distributed.<br/>&gt;&gt;<br/>&gt;&gt; In my dispatcher, I register every host. For each host I create a watcher :<br/>&gt;&gt;<br/>&gt;&gt; $self-&gt;{hosts}{$host}{watcher} =<br/>&gt;&gt; Event-&gt;var(desc =&gt;&quot;Process sentence on $host&quot;,<br/>&gt;&gt; var =&gt; \$client-&gt;{free},<br/>&gt;&gt; poll =&gt; &#39;w&#39;,<br/>&gt;&gt; cb =&gt; $self-&gt;next_dag($host),<br/>&gt;&gt; debug =&gt; 4,<br/>&gt;&gt; );<br/>&gt;&gt;<br/>&gt;&gt; The callback next_dag is called every time all the process of parsing<br/>&gt;&gt; the sentence and sending back the results is done (more precisely when<br/>&gt;&gt; the host says it&#39;s ready to receive a new sentence, with variable<br/>&gt;&gt; $client-&gt;{free}).<br/>&gt;&gt;<br/>&gt;&gt; Of course, I would like that every host can work at the same time<br/>&gt;&gt; (that&#39;s the point...), but my problem is that they do the job<br/>&gt;&gt; subsequently, one sentence at the time.<br/>&gt;&gt;<br/>&gt;&gt; The created event mainly does the following:<br/>&gt;&gt; - get the next sentence from a file<br/>&gt;&gt; - send this sentence to the parser on the free host (through a server of<br/>&gt;&gt; parser accessed with Net::Telnet)<br/>&gt;&gt; - get the result of the parsing (yes or no) (still through Net::Telnet...)<br/>&gt;&gt; - if yes, connect again to the server of parser to generate one or<br/>&gt;&gt; several outputs and write them into one or several files<br/>&gt;&gt; - says &quot;I&#39;m ready to get a new sentence to parse&quot;, triggering the<br/>&gt;&gt; variable &#39;free&#39;<br/>&gt;&gt;<br/>&gt;&gt; I thought that creating an event was automatically non blocking and<br/>&gt;&gt; several events could happen at the same time. Does the problem come from<br/>&gt;&gt; the I/O interactions ? If so, do I need to separate all these stages and<br/>&gt;&gt; watch for every I/O interactions ? And do I need to specify somewhere<br/>&gt;&gt; that I want non blocking I/O ?<br/>&gt;&gt;<br/>&gt;&gt; Best regards,<br/>&gt;&gt; Isabelle<br/>&gt;&gt;<br/>&gt;&gt; --<br/>&gt;&gt; Isabelle Cabrera<br/>&gt;&gt; Projet Alpage - INRIA Rocquencourt<br/>&gt;&gt; http://alpage.inria.fr<br/>&gt;&gt; Tel : 01 3963 5270<br/>&gt;&gt;<br/>&gt;&gt;<br/>&gt;&gt; <br/>&gt;<br/>&gt; it sounds like each event is blocking, waiting for the computation to<br/>&gt; return a result, and then releasing to allow EV to continue it&#39;s loop.<br/>&gt; i have had a similar problem recently, (a multi-server irc bot), and<br/>&gt; found i have a similar problem, each time the event was blocking and<br/>&gt; waiting for a reply.<br/>&gt;<br/>&gt; how i solved it was to create a readable event for each socket, so<br/>&gt; rather than send-wait-receive as you have, its send, then assign a<br/>&gt; receive callback to trigger when a result is returned. thus, send<br/>&gt; commands down each socket, and allow EV to loop until each one<br/>&gt; returns, and as each result is returned, send another query, then let<br/>&gt; EV wait on the result again, ad infinitum.<br/>&gt;<br/>&gt; i suspect this is a horribly confusing answer, and unfortunately i&#39;m<br/>&gt; away from home for a few days so i cant provide a code example, but<br/>&gt; feel free to ask anything further.<br/>&gt;<br/>&gt; James Clark.<br/>&gt; <br/>Thank you James. Finally my problem comes from the fact that my I/O <br/>interactions are blocking. So instead of using Net::Telnet I&#39;m trying to <br/>use IO::Socket to do non blocking I/O.<br/>One other problem is that I had a huge callback, so I&#39;m going to split <br/>up my code in smaller peaces.<br/><br/>Best regards,<br/>Isabelle Cabrera<br/><br/>-- <br/>Isabelle Cabrera<br/>Equipe-Projet Alpage - INRIA Paris-Rocquencourt<br/>http://alpage.inria.fr<br/>Tel : 01 3963 5270<br/><br/> http://www.nntp.perl.org/group/perl.loop/2008/06/msg1123.html Wed, 04 Jun 2008 05:47:34 +0000 Re: non blocking issue ? by `Zidane Tribal On 28/05/2008, Isabelle Cabrera &lt;isabelle.cabrera@inria.fr&gt; wrote:<br/>&gt; Hi,<br/>&gt;<br/>&gt; I have a problem using the Event module.<br/>&gt;<br/>&gt; My goal: I have several sentences that I need to parse. For a faster<br/>&gt; process, I have a dispatcher which sends the sentences to several hosts<br/>&gt; so that the processes are distributed.<br/>&gt;<br/>&gt; In my dispatcher, I register every host. For each host I create a watcher :<br/>&gt;<br/>&gt; $self-&gt;{hosts}{$host}{watcher} =<br/>&gt; Event-&gt;var(desc =&gt;&quot;Process sentence on $host&quot;,<br/>&gt; var =&gt; \$client-&gt;{free},<br/>&gt; poll =&gt; &#39;w&#39;,<br/>&gt; cb =&gt; $self-&gt;next_dag($host),<br/>&gt; debug =&gt; 4,<br/>&gt; );<br/>&gt;<br/>&gt; The callback next_dag is called every time all the process of parsing<br/>&gt; the sentence and sending back the results is done (more precisely when<br/>&gt; the host says it&#39;s ready to receive a new sentence, with variable<br/>&gt; $client-&gt;{free}).<br/>&gt;<br/>&gt; Of course, I would like that every host can work at the same time<br/>&gt; (that&#39;s the point...), but my problem is that they do the job<br/>&gt; subsequently, one sentence at the time.<br/>&gt;<br/>&gt; The created event mainly does the following:<br/>&gt; - get the next sentence from a file<br/>&gt; - send this sentence to the parser on the free host (through a server of<br/>&gt; parser accessed with Net::Telnet)<br/>&gt; - get the result of the parsing (yes or no) (still through Net::Telnet...)<br/>&gt; - if yes, connect again to the server of parser to generate one or<br/>&gt; several outputs and write them into one or several files<br/>&gt; - says &quot;I&#39;m ready to get a new sentence to parse&quot;, triggering the<br/>&gt; variable &#39;free&#39;<br/>&gt;<br/>&gt; I thought that creating an event was automatically non blocking and<br/>&gt; several events could happen at the same time. Does the problem come from<br/>&gt; the I/O interactions ? If so, do I need to separate all these stages and<br/>&gt; watch for every I/O interactions ? And do I need to specify somewhere<br/>&gt; that I want non blocking I/O ?<br/>&gt;<br/>&gt; Best regards,<br/>&gt; Isabelle<br/>&gt;<br/>&gt; --<br/>&gt; Isabelle Cabrera<br/>&gt; Projet Alpage - INRIA Rocquencourt<br/>&gt; http://alpage.inria.fr<br/>&gt; Tel : 01 3963 5270<br/>&gt;<br/>&gt;<br/><br/>it sounds like each event is blocking, waiting for the computation to<br/>return a result, and then releasing to allow EV to continue it&#39;s loop.<br/> i have had a similar problem recently, (a multi-server irc bot), and<br/>found i have a similar problem, each time the event was blocking and<br/>waiting for a reply.<br/><br/>how i solved it was to create a readable event for each socket, so<br/>rather than send-wait-receive as you have, its send, then assign a<br/>receive callback to trigger when a result is returned. thus, send<br/>commands down each socket, and allow EV to loop until each one<br/>returns, and as each result is returned, send another query, then let<br/>EV wait on the result again, ad infinitum.<br/><br/>i suspect this is a horribly confusing answer, and unfortunately i&#39;m<br/>away from home for a few days so i cant provide a code example, but<br/>feel free to ask anything further.<br/><br/>James Clark.<br/> http://www.nntp.perl.org/group/perl.loop/2008/06/msg1122.html Sun, 01 Jun 2008 09:27:51 +0000 non blocking issue ? by Isabelle Cabrera Hi,<br/><br/>I have a problem using the Event module.<br/><br/>My goal: I have several sentences that I need to parse. For a faster <br/>process, I have a dispatcher which sends the sentences to several hosts <br/>so that the processes are distributed.<br/><br/>In my dispatcher, I register every host. For each host I create a watcher :<br/><br/> $self-&gt;{hosts}{$host}{watcher} =<br/> Event-&gt;var(desc =&gt;&quot;Process sentence on $host&quot;,<br/> var =&gt; \$client-&gt;{free},<br/> poll =&gt; &#39;w&#39;,<br/> cb =&gt; $self-&gt;next_dag($host),<br/> debug =&gt; 4,<br/> );<br/><br/>The callback next_dag is called every time all the process of parsing <br/>the sentence and sending back the results is done (more precisely when <br/>the host says it&#39;s ready to receive a new sentence, with variable <br/>$client-&gt;{free}).<br/><br/>Of course, I would like that every host can work at the same time <br/>(that&#39;s the point...), but my problem is that they do the job <br/>subsequently, one sentence at the time.<br/><br/>The created event mainly does the following:<br/>- get the next sentence from a file<br/>- send this sentence to the parser on the free host (through a server of <br/>parser accessed with Net::Telnet)<br/>- get the result of the parsing (yes or no) (still through Net::Telnet...)<br/>- if yes, connect again to the server of parser to generate one or <br/>several outputs and write them into one or several files<br/>- says &quot;I&#39;m ready to get a new sentence to parse&quot;, triggering the <br/>variable &#39;free&#39;<br/><br/>I thought that creating an event was automatically non blocking and <br/>several events could happen at the same time. Does the problem come from <br/>the I/O interactions ? If so, do I need to separate all these stages and <br/>watch for every I/O interactions ? And do I need to specify somewhere <br/>that I want non blocking I/O ?<br/><br/>Best regards,<br/>Isabelle<br/><br/>-- <br/>Isabelle Cabrera<br/>Projet Alpage - INRIA Rocquencourt<br/>http://alpage.inria.fr<br/>Tel : 01 3963 5270<br/><br/> http://www.nntp.perl.org/group/perl.loop/2008/05/msg1121.html Wed, 28 May 2008 08:48:34 +0000 announcing AnyEvent 4.0 by Marc Lehmann I am pleased to announce AnyEvent 4.0<br/><br/>Why the major version bump?<br/><br/> Lots of functionality has been added (and thus some bugs are expected),<br/> although the event core is still compatible to earlier versions and AnyEvent<br/> is still pure-perl without any (hard) dependencies on any XS modules.<br/><br/>So whats new?<br/><br/> Apart from a number of bugfixes, the AnyEvent::Socket module has been<br/> added. It contains a lot of utility functions to handle IPv4 and IPv6<br/> addresses and tcp connections in a 100% non-blocking way. It supports SRV<br/> record lookups.<br/><br/> To make the 100% non-blocking a reality, AnyEvent::Socket uses<br/> AnyEvent::DNS, a fully asynchronous stub resolver capable of making tens<br/> of thousands of DNS requests/second, with TCP and EDNS0 support.<br/><br/> And if you have Net::SSLeay installed, then AnyEvent::Handle can<br/> transparently manage TLS/SSL connections, too.<br/><br/> On the microshit windows side, AnyEvent now tries very hard to avoid<br/> the freeze in the testsuite on broken perls (with reduced functionality,<br/> but resolver and socket code works fine there, too).<br/><br/> The distro should hit the CPAN mirrors in a few hours. Documentation<br/> can be found via its homepage, http://software.schmorp.de/pkg/AnyEvent<br/><br/>Example:<br/><br/> This (pseudo-) code snippet connects to jabber server, by querying any SRV records<br/> that might exist and connecting to the resulting addresses in turn -<br/> regardless of wether the server uses ip version 4 or ip version 6 (or<br/> both):<br/><br/> AnyEvent::Socket::tcp_connect &quot;jabber.ietf.org&quot;, &quot;xmpp-client&quot;,<br/> sub {<br/> my ($fh) = @_<br/> or die &quot;connect: $!&quot;;<br/><br/> my $handle;<br/> $handle = new AnyEvent::Handle<br/> fh =&gt; $fh,<br/> on_eof =&gt; sub {<br/> undef $handle; # destroy handle on eof<br/> },<br/> ;<br/><br/> # etc..<br/> # when server and client handshake a SSL connection, one can simply<br/> # call $handle-&gt;starttls (&quot;connect&quot;) to start ssl negotiation.<br/><br/> # push some writes or soem reads here, or set some callbacks<br/> };<br/><br/> This (non-pseudo-code) code snippet asynchronously connects to<br/> https://www.google.de and makes a simple GET request:<br/><br/> use AnyEvent::Impl::Perl; # use portable perl event loop<br/> use AnyEvent::Handle;<br/> use AnyEvent::Socket;<br/><br/> my $cv = AnyEvent-&gt;condvar;<br/><br/> AnyEvent::Socket::tcp_connect &quot;www.google.de&quot;, 443,<br/> sub {<br/> my ($fh) = @_<br/> or die &quot;connect: $!&quot;;<br/><br/> my $handle; # avoid direct assignment so on_eof has it in scope.<br/> $handle = new AnyEvent::Handle<br/> fh =&gt; $fh,<br/> tls =&gt; &quot;connect&quot;, # start client-side tls negotiation<br/> on_eof =&gt; sub {<br/> undef $handle; # keep it alive till eof<br/> warn &quot;done.\n&quot;;<br/> $cv-&gt;send;<br/> };<br/><br/> $handle-&gt;push_write (&quot;GET / HTTP/1.0\015\012\015\012&quot;);<br/><br/> $handle-&gt;push_read_line (&quot;\015\012\015\012&quot;, sub {<br/> my ($handle, $line) = @_;<br/><br/> # print response header<br/> print &quot;HEADER\n$line\n\nBODY\n&quot;;<br/><br/> $handle-&gt;on_read (sub {<br/> # print response body<br/> print $_[0]-&gt;rbuf;<br/> $_[0]-&gt;rbuf = &quot;&quot;;<br/> });<br/> });<br/> };<br/><br/> $cv-&gt;recv;<br/><br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/05/msg1120.html Sat, 24 May 2008 11:28:22 +0000 Re: benchmarking various event loops with and without anyevent by Rocco Caputo On Apr 28, 2008, at 03:21, Marc Lehmann wrote:<br/>&gt;<br/>&gt; In all fairness, I want to point out that, after _multiple_ rounds of<br/>&gt; longish e-mail exchanges, Rocco Caputo could not solve the problems <br/>&gt; that<br/>&gt; forced AnyEvent to use this design, nor did he enlighten me on how <br/>&gt; to work<br/>&gt; around the specific problems that I mentioned to him that forced this<br/>&gt; design decision(*).<br/><br/><br/>Addressed in &lt;629C022B-BF10-4461-9D52-8F305D2051DC@pobox.com&gt;. Please <br/>respond there.<br/><br/>&gt; He did not come up with any further evidence for a problem, either <br/>&gt; (just<br/>&gt; repeatedly stating that the design is broken. The only argument he <br/>&gt; brought<br/>&gt; up was: one of your design goals is to be reasonably efficient, POE <br/>&gt; does<br/>&gt; not do it reasonably efficient, so your design is broken, which is an<br/>&gt; outright absurd logic).<br/><br/>Marc and I are disagreeing with what I wrote in the message included <br/>in &lt;E5761512-9F7F-45ED-9C45-A8D9FFFC8C9C@pobox.com&gt;. No amount of he- <br/>said/no-he-said will resolve it at this point, so I refer the reader <br/>back to the actual exchange.<br/><br/>Everyone: Your suggestions to improve my communication are greatly <br/>appreciated. Please comment off-list, if you can.<br/><br/>&gt; In fact, it seems his problem is indeed the AnyEvent API and not the<br/>&gt; interface module to POE, i.e. the &quot;broken&quot; means I should not provide<br/>&gt; events in the form AnyEvent does, which is of course <br/>&gt; counterproductive to<br/>&gt; the goal of AnyEvent of being compatible to multiple event loops (I <br/>&gt; can&#39;t<br/>&gt; provide different APIs to different event loops...).<br/><br/>I explicitly stated otherwise in the message included in &lt;E5761512-9F7F-45ED-9C45-A8D9FFFC8C9C@pobox.com <br/> &gt;. It&#39;s the sentence beginning with &quot;We should not need to change <br/>AnyEvent::Impl::POE&#39;s public interface&quot;.<br/><br/>&gt; So I conclude that even the POE author is unable to provide a <br/>&gt; (strongly)<br/>&gt; more efficient approach, which, according to his own words, would <br/>&gt; make him<br/>&gt; worse then the average first-time POE user.<br/><br/>Considering our previous discussions on the matter, I feel that your <br/>conclusion is premature.<br/><br/>Also, you seem to be saying that one solution can simultaneously <br/>perform equally as well as another and worse than it. Which quantum <br/>computers have you ported AnyEvent to lately? :)<br/><br/>-- <br/>Rocco Caputo - rcaputo@pobox.com<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1119.html Mon, 28 Apr 2008 14:19:03 +0000 Re: benchmarking various event loops with and without anyevent by Rocco Caputo On Apr 28, 2008, at 06:24, Marc Lehmann wrote:<br/>&gt; [most important points first]<br/>&gt;<br/>&gt;&gt; In your case, I would create a single persistent POE::Session <br/>&gt;&gt; instance<br/>&gt;&gt; that serviced all the watchers.<br/>&gt;<br/>&gt; I would, too, but I cannot find a way to do that with POE: sessions<br/>&gt; without active watchers will be destroyed, forcing the session to have<br/>&gt; active resources will make the program never-ending.<br/>&gt;<br/>&gt; I already told you that I tried this approach, and why I couldn&#39;t <br/>&gt; get it<br/>&gt; working.<br/><br/>I might use something like an explicit reference count to keep the <br/>session alive. I would create a proxy object that, when DESTROYed, <br/>would post a shutdown message to the session. Or if AnyEvent knows <br/>when a program is to exit, I would have it explicitly shutdown the <br/>session as part of its finalization.<br/><br/>The shutdown handler would remove the explicit reference count, <br/>allowing the session to stop.<br/><br/>It&#39;s similar to the technique you use in AnyEvent::Impl::POE:<br/><br/>sub DESTROY {<br/> POE::Kernel-&gt;post (${${$_[0]}}, &quot;stop&quot;);<br/>}<br/><br/>Except it would be done once at the very end, rather than for each <br/>event watcher.<br/><br/>Perhaps this isn&#39;t necessary. You&#39;re not using run(), so technically <br/>you&#39;re free to go at any time. If your program must exit while <br/>watchers are active, then you could force the issue by sending a <br/>global UIDESTROY signal (designed to tell POE when it must <br/>unconditionally stop), and calling run():<br/><br/>$poe_kernel-&gt;signal($poe_kernel, &quot;UIDESTROY&quot;);<br/>$poe_kernel-&gt;run();<br/><br/>On the other hand, your AnyEvent::Impl::POE proxy objects could also <br/>hold references to the singleton session, and if they release those <br/>references when they clean up their POE::Kernel resources, the session <br/>should be &quot;empty&quot; by the time they all destruct. In that case, the <br/>UIDESTROY signal should not be needed. run() will return after <br/>removing the &quot;empty&quot; session.<br/><br/>In short, your AnyEvent::Impl::POE objects would be of the form:<br/><br/>sub new {<br/> # (AnyEvent::Impl::POE setup goes here)<br/> # set up the POE::Kernel watcher<br/> $poe_kernel-&gt;something(something);<br/> # make a note of the watcher in this object<br/> $self-&gt;{something} = $record_of_the_poe_watcher;<br/> return $self;<br/>}<br/><br/>sub DESTROY {<br/> my $self = shift;<br/> # ... release the POE::Kernel watcher<br/> $poe_kernel-&gt;something($self-&gt;{something}, something);<br/>}<br/><br/>If you expect the user to be creating their own POE::Session <br/>instances, then you&#39;d need to call() AnyEvent::Impl::POE to make sure <br/>the watchers are created in the right context.<br/><br/>sub new {<br/> # (AnyEvent::Impl::POE setup goes here)<br/> # set up the POE::Kernel watcher<br/> $poe_kernel-&gt;call(&quot;anyevent_impl_poe&quot;, &quot;something&quot;, something);<br/> # make a note of the watcher in this object<br/> $self-&gt;{something} = $record_of_the_poe_watcher;<br/> return $self;<br/>}<br/><br/>And DESTROY would tell the session when to clear the watcher.<br/><br/>You may need to add a new AnyEvent::Impl method to explicitly stop <br/>POE, especially if your public API allows users to exit with active <br/>watchers.<br/><br/>sub shutdown {<br/> $poe_kernel-&gt;signal($poe_kernel, &quot;UIDESTROY&quot;);<br/> POE::Kernel-&gt;run();<br/>}<br/><br/>As an added bonus, shutting down this way satisfies the run() warning.<br/><br/>I know this isn&#39;t a full solution, but I hope you still find it helpful.<br/><br/>&gt; You kepe repeating how it could be designed better, but you never <br/>&gt; actually<br/>&gt; say how to solve the fundamental problems and bugs within POE that <br/>&gt; keep it<br/>&gt; from being implementable.<br/><br/>I would be welcome to discuss the code more than each-other. If we <br/>can agree on this, perhaps we can get down to more important matters. <br/>See above.<br/><br/>&gt; As I said, if possible, I can only imagine the design becoming <br/>&gt; vastly more<br/>&gt; complex because I would have to create sdessions on demand and be <br/>&gt; able to<br/>&gt; react to my session beign turned down at unopportune times.<br/><br/>I don&#39;t understand why this design is necessary. Please help me <br/>understand your design constraints, so that I may focus on designs <br/>that will work.<br/><br/>&gt; What we seem to agree on by now is that such a design is not trivial <br/>&gt; to do<br/>&gt; with POE.<br/>&gt;<br/>&gt; Also, remember that the benchmarks show that session creation is not<br/>&gt; the big problem, running the sesions is - of course, there could be<br/>&gt; inefficiencies in POE handling large number of sessions, but that <br/>&gt; means<br/>&gt; just that - POE doesn&#39;t scale well.<br/><br/>While my suggestions are not as trivial as your current design, I <br/>don&#39;t think the end design will be as complex as you expect.<br/><br/>Thank you for your feedback. I&#39;m sorry that POE doesn&#39;t meet your <br/>needs. When I have the chance, I&#39;ll profile POE while running your <br/>benchmark and see what I can do.<br/><br/>&gt; As the documentation mentions, AnyEvent doesn&#39;t enforce itself on a<br/>&gt; module, unlike POE - a module using POE is not going to work with <br/>&gt; other<br/>&gt; event loops, because it monopolises the process.<br/>&gt;<br/><br/>&gt; This means that a module using POE forces all its users to also use <br/>&gt; POE.<br/><br/>This is factually incorrect. For example, POE::Loop::Glib allows POE <br/>to be embedded into applications like vim and irssi. The <br/>application&#39;s functionality is not impaired, nor is communication <br/>between the native scripting elements and the embedded POE code.<br/><br/>POE defers to the native event loop whenever possible. For example, <br/>the main loop from POE::Loop::Gtk:<br/><br/>sub loop_run {<br/> unless (defined $_watcher_timer) {<br/> $_watcher_timer = Gtk-&gt;idle_add(\&amp;_loop_resume_timer);<br/> }<br/> Gtk-&gt;main;<br/>}<br/><br/>In cases where issues prevent POE from using the native loop, a custom <br/>loop is written around the native DoOneEvent() (or equivalent) <br/>dispatcher.<br/><br/>&gt; This is a fundamental difference between POE and AnyEvent, it has <br/>&gt; nothing<br/>&gt; to do with event loop backend modules, of which POE also emplys a <br/>&gt; few, but<br/>&gt; comes form the fact that you have to call POE::Kernel-&gt;run and give up<br/>&gt; your process to it (just like with EV::loop etc.)<br/><br/>I believe the above loop_run() above shows this to be factually <br/>incorrect. Even when POE::Kernel-&gt;run() is called, execution is <br/>passed back to the native event loop.<br/><br/>AnyEvent::Impl::POE doesn&#39;t relinquish control to POE::Kernel-&gt;run(), <br/>so it seems to conflict with your claim.<br/><br/>&gt; On Mon, Apr 28, 2008 at 04:36:42AM -0400, Rocco Caputo &lt;rcaputo@pobox.com <br/>&gt; &gt; wrote:<br/>&gt;<br/>&gt;&gt; Are you aware that I&#39;m gradually rewriting POE&#39;s documentation? If<br/>&gt;&gt; you could describe what you don&#39;t like in a useful way, I may be able<br/>&gt;&gt; to do something about it.<br/>&gt;<br/>&gt; Since I described it already (and you know that) it means you find <br/>&gt; the way<br/>&gt; I did it &quot;not useful&quot;. Thats a strawman argument. If you don&#39;t like my<br/>&gt; criticism or don&#39;t understand it, ask.<br/><br/>Okay, I will ask. In all cases, please include sufficient information <br/>in your reply so that I can find the documentation in question.<br/><br/>What is inaccurate? How is it inaccurate?<br/>What parts could I improve? How could I improve them?<br/>What is missing?<br/>What isn&#39;t necessary?<br/>If I&#39;ve overlooked a question to ask, please let me know, and I will <br/>ask it.<br/><br/>&gt; It is fine with me if you don&#39;t understand AnyEvent, it is somewhat <br/>&gt; fine<br/>&gt; with me if you make strong (But wrong) statements about it, but don&#39;t<br/>&gt; expect anybody to put much faith in them, or you ability to make <br/>&gt; useful<br/>&gt; statements.<br/><br/>Back at you. See above for some examples where your strong statements <br/>against POE have been incorrect.<br/><br/>As I&#39;ve said before, I&#39;d like to resolve these misunderstandings so <br/>that we can move forward in a more amicable and efficient fashion. If <br/>we can eventually exhaust our misconceptions by thoroughly addressing <br/>them, then perhaps we can move on to more productive things.<br/><br/>&gt;&gt; Assuming that N is the same between the equivalent POE and<br/>&gt;&gt; AnyEvent::Impl::POE program:<br/>&gt;&gt;<br/>&gt;&gt; S(N*M) &gt; S(N) for M &gt; 1.<br/>&gt;&gt;<br/>&gt;&gt; QED :P<br/>&gt;<br/>&gt; I couldn&#39;t really follow you here, and I am not sure what you have <br/>&gt; proven. To<br/>&gt; me it certainly looks as if it was &quot;POE cannot support the AnyEvent <br/>&gt; API<br/>&gt; efficiently&quot; (at leats not in a simple and straightforward way).<br/><br/>I don&#39;t know how to be more explicit, unambiguous, and emotionally <br/>neutral than by modeling the overhead mathematically. If that&#39;s <br/>insufficient, then I&#39;m at a loss for how to proceed.<br/><br/>&gt;&gt;&gt; I can only imagine making some very complex on-demand <br/>&gt;&gt;&gt; instantiating and<br/>&gt;&gt;&gt; re- check wether the session still exists on each watcher creation.<br/>&gt;&gt;<br/>&gt;&gt; Your imagination comes up with such incredible things. Don&#39;t lose<br/>&gt;&gt; that. :)<br/>&gt;<br/>&gt; Overbearing words after being wrong before.<br/><br/>My bad. It&#39;s a long message, and I had to let off some steam. On a <br/>more positive note, you do have an inventive mind, and I really do <br/>hope that you never lose that quality.<br/><br/>&gt;&gt; I use this design in POE::Stage.<br/>&gt;<br/>&gt; Does it survice multiple run&#39;s? If yes, how so?<br/><br/>I&#39;m not sure that multiple run()s is a relevant issue. Your code <br/>seems to get along without calling run() at all.<br/><br/>The number of POE::Session instances has no bearing on whether you can <br/>continue using loop_do_timeslice().<br/><br/>I am obviously overlooking something. If you could explain what that <br/>is, we could put this detail to rest and move on.<br/><br/>&gt;&gt;&gt; (the race condition with sigchld is really annoying,<br/>&gt;&gt;<br/>&gt;&gt; Please describe the race condition in a useful way, so that I can<br/>&gt;&gt; investigate and possibly fix it.<br/>&gt;<br/>&gt; Again the red herring &quot;useful&quot; - it obviously was useful enough for <br/>&gt; other<br/>&gt; people to understand the issue. The problem is that rgeistering a <br/>&gt; watcher<br/>&gt; after the child process already exited causes POE to introduce a <br/>&gt; delay in<br/>&gt; reapign the child (it does seem to do polling to do so, and seems to <br/>&gt; do so<br/>&gt; once per second, so the delay is at most a second, still, thats a <br/>&gt; pretty<br/>&gt; long time).<br/><br/>[more specifics snipped]<br/><br/>A useful report is one that can be use to replicate or isolate the <br/>problem. Saying &quot;the race condition with sigchld&quot; is not useful. <br/>Being more specific, as you have just done, is VERY useful. Thank you!<br/><br/>An experimental fix for what you describe has already been released. <br/>Because it&#39;s experimental, you will need to enable it manually. <br/>Please verify you&#39;re using the most recent POE, and check <br/>POE::Kernel&#39;s documentation for &quot;USE_SIGCHLD&quot;.<br/><br/>It appears that the sig_child() documentation conflicts with the <br/>USE_SIGCHLD documentation. I have fixed it for the next release.<br/><br/>&gt;&gt;&gt; The &quot;run() method was never called&quot; message can be silenced by <br/>&gt;&gt;&gt; calling<br/>&gt;&gt; run(). Not all applications require run(). But if you call it<br/>&gt;&gt; without any POE::Session instances, it will return immediately and<br/>&gt;&gt; satisfy POE::Kernel.<br/>&gt;<br/>&gt; This is impossible it guarentee from within AnyEvent.<br/>&gt;<br/>&gt; So there is no way to silence just the message.<br/>[...]<br/>&gt; AnyEvent::Impl::POE already invokes the run workaround in its <br/>&gt; manpage, and<br/>&gt; why it is undesirable. This puts an unecessary burden on the user, <br/>&gt; and is<br/>&gt; certainly an issue.<br/><br/>Your code already silences this warning, so I don&#39;t know why you keep <br/>saying it can&#39;t be done:<br/><br/># have to do this to keep POE from spilling ugly messages<br/>POE::Session-&gt;create (inline_states =&gt; { _start =&gt; sub { @_[KERNEL]- <br/> &gt;stop } });<br/>POE::Kernel-&gt;run;<br/><br/>Unless AnyEvent is doing something I don&#39;t know, you should be able to <br/>drop the POE::Session-&gt;create() line without any harm.<br/><br/>&gt;&gt; You complain about a message that occurs when a program leaks a child<br/>&gt;&gt; process. Programs that leak processes are broken in a way that is<br/>&gt;&gt; difficult to detect without the warning. In extreme cases, process<br/>&gt;&gt; leakage can quietly strangle a machine to death.<br/>&gt;<br/>&gt; No, I complain about the emssage complaining about POE reaping a <br/>&gt; child. No<br/>&gt; leak is involved anywhere, and nothign will &quot;quietly&quot; &quot;strangle&quot; <br/>&gt; anything<br/>&gt; to death.<br/><br/>The message I&#39;m thinking of occurs at the end of the program when POE <br/>checks whether any child processes remain. Exiting without reaping <br/>children is considered bad form and can lead to orphan processes on <br/>some systems, so POE enforces this behavior. The warning indicates <br/>that the application has not been looking after its children.<br/><br/>POE doesn&#39;t reap children unless there is a sig_child() watcher. <br/>Therefore, if your program is long-running, spawns processes during <br/>its normal operation, and fails to trigger reaping, it will eventually <br/>exhaust its process resources.<br/><br/>If the application runs as root, there will often be no ulimit guard <br/>preventing zombie processes from filling up the system&#39;s process <br/>table. If this happens, the system will most likely become <br/>unresponsive and need to be restarted.<br/><br/>I consider such applications to be broken. You are welcome to think <br/>otherwise, but POE will continue to point out when this happens.<br/><br/>The most direct solution is for an application to set sig_child() <br/>handlers for the children it creates. This will trigger reaping, and <br/>the warnings (and potential for catastrophe) will go away.<br/><br/>&gt;&gt; OMG, we agree on something! The end times are here:<br/><br/>&gt;<br/>&gt; sorry?<br/><br/>It&#39;s a joke. You see, we agree on so little, so actually agreeing on <br/>something is a momentous event. I was humorously drawing parallels to <br/>events that signal the impending end of the world in some religions. <br/>The &quot;end times&quot; are also conveniently where I finished my e-mail. <br/>It&#39;s a bit of a pun, really.<br/><br/>-- <br/>Rocco Caputo - rcaputo@pobox.com<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1118.html Mon, 28 Apr 2008 12:51:45 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann [most important points first]<br/><br/>&gt; In your case, I would create a single persistent POE::Session instance <br/>&gt; that serviced all the watchers.<br/><br/>I would, too, but I cannot find a way to do that with POE: sessions<br/>without active watchers will be destroyed, forcing the session to have<br/>active resources will make the program never-ending.<br/><br/>I already told you that I tried this approach, and why I couldn&#39;t get it<br/>working.<br/><br/>You kepe repeating how it could be designed better, but you never actually<br/>say how to solve the fundamental problems and bugs within POE that keep it<br/>from being implementable.<br/><br/>As I said, if possible, I can only imagine the design becoming vastly more<br/>complex because I would have to create sdessions on demand and be able to<br/>react to my session beign turned down at unopportune times.<br/><br/>What we seem to agree on by now is that such a design is not trivial to do<br/>with POE.<br/><br/>Also, remember that the benchmarks show that session creation is not<br/>the big problem, running the sesions is - of course, there could be<br/>inefficiencies in POE handling large number of sessions, but that means<br/>just that - POE doesn&#39;t scale well.<br/><br/>On Mon, Apr 28, 2008 at 04:36:42AM -0400, Rocco Caputo &lt;rcaputo@pobox.com&gt; wrote:<br/>&gt; Most people on the planet don&#39;t know Perl, or even how to program a <br/>&gt; computer. No amount of documentation will help them. :)<br/><br/>Good (or any) documentation is widely known to be almost a _requirement_<br/>for learning how to program or use a software package.<br/><br/>&gt; In the future, you may wish to include me on your list of people to <br/>&gt; consult about designing applications for POE. I may known a thing or <br/>&gt; two about the topic. :)<br/><br/>I am not interested in designing applications for POE - I am interested in<br/>making it possible to write event-based modules that are interoperable<br/>between various event loops such as POE.<br/><br/>As the documentation mentions, AnyEvent doesn&#39;t enforce itself on a<br/>module, unlike POE - a module using POE is not going to work with other<br/>event loops, because it monopolises the process.<br/><br/>This means that a module using POE forces all its users to also use POE.<br/><br/>AnyEvent does not do that, as long as it supports the event model actually<br/>in use (it is not an event loop itself!): A module that uses AnyEvent<br/>works with both Qt, POE, IO::Async (once its backend is implemented), EV<br/>and so on.<br/><br/>This is a fundamental difference between POE and AnyEvent, it has nothing<br/>to do with event loop backend modules, of which POE also emplys a few, but<br/>comes form the fact that you have to call POE::Kernel-&gt;run and give up<br/>your process to it (just like with EV::loop etc.)<br/><br/>&gt; Are you aware that I&#39;m gradually rewriting POE&#39;s documentation? If <br/>&gt; you could describe what you don&#39;t like in a useful way, I may be able <br/>&gt; to do something about it.<br/><br/>Since I described it already (and you know that) it means you find the way<br/>I did it &quot;not useful&quot;. Thats a strawman argument. If you don&#39;t like my<br/>criticism or don&#39;t understand it, ask.<br/><br/>&gt; I would love to have the opportunity to suggest a different design, <br/><br/>You always ahd the opportunity, you are not using it.<br/><br/>&gt; Obviously I cannot expect you to know everything about POE. Likewise, <br/>&gt; you cannot expect me to magically know when you started writing <br/>&gt; AnyEvent::Impl::POE.<br/><br/>It doesn&#39;t matter when I started writing AnyEvent::Impl::POE at all. What<br/>matters is that you made unfounded (and as you now admit, wrong)<br/>statements about it (and its author).<br/><br/>It is fine with me if you don&#39;t understand AnyEvent, it is somewhat fine<br/>with me if you make strong (But wrong) statements about it, but don&#39;t<br/>expect anybody to put much faith in them, or you ability to make useful<br/>statements.<br/><br/>&gt; Even if you announced it somewhere, I may not have been looking. The<br/>&gt; first I heard of it was here, when you announced your benchmarks.<br/><br/>Yes, so?<br/><br/>&gt; In general, if you need someone&#39;s attention online, the most effective <br/>&gt; and polite way is to contact them directly.<br/><br/>I did not need your attention?<br/><br/>&gt; about this, then I&#39;m sorry that I missed it. Are you sure your <br/>&gt; message wasn&#39;t lost in transit?<br/><br/>Which message? I was only conveying some benchmark results, to give<br/>people an idea of the overheads of AnyEvent of various event loop<br/>implementations in the hope of beign useful.<br/><br/>I was also hoping that people might give AnyEvent some try, as it&#39;s design<br/>doesn&#39;t force a module author using it into a specific event loop.<br/><br/>&gt; Assuming that N is the same between the equivalent POE and <br/>&gt; AnyEvent::Impl::POE program:<br/>&gt; <br/>&gt; S(N*M) &gt; S(N) for M &gt; 1.<br/>&gt; <br/>&gt; QED :P<br/><br/>I couldn&#39;t really follow you here, and I am not sure what you have proven. To<br/>me it certainly looks as if it was &quot;POE cannot support the AnyEvent API<br/>efficiently&quot; (at leats not in a simple and straightforward way).<br/><br/>I knew that already.<br/><br/>&gt; &gt;I can only imagine making some very complex on-demand instantiating and<br/>&gt; &gt;re- check wether the session still exists on each watcher creation.<br/>&gt; <br/>&gt; Your imagination comes up with such incredible things. Don&#39;t lose <br/>&gt; that. :)<br/><br/>Overbearing words after being wrong before.<br/><br/>&gt; The &quot;trick&quot; is to minimize the number of sessions used.<br/><br/>I already said that, and explaiend why it didn&#39;t work.<br/><br/>&gt; that sessions imposed overhead. I wrongly assumed the solution would <br/>&gt; be obvious.<br/><br/>Yes.<br/><br/>&gt; I use this design in POE::Stage.<br/><br/>Does it survice multiple run&#39;s? If yes, how so?<br/><br/>&gt; experimental code, you can find it on the CPAN. It also does a lot of <br/>&gt; other, unrelated things, so you may have difficulty separating the <br/>&gt; magic you need from the voodoo you don&#39;t.<br/><br/>As I said, less magic and vodoo and better documentation could be more<br/>helpful in the long run.<br/><br/>I don&#39;t see how POE::Stage solves the problem of multiple run&#39;s stopping<br/>sessions. If it does, couldn&#39;t you just advise me on how to do it insteadf<br/>of referring to bugloads of other code? Either you know how to solve the<br/>issues, then just tell us, or you don&#39;t, in which case going through large<br/>amounts of code won&#39;t help.<br/><br/>&gt; I won&#39;t blame you. But I will point out that your documentation says <br/>&gt; you&#39;re already familiar with using undocumented POE features. :)<br/><br/>Yes indeed :/<br/><br/>&gt; &gt;Instead of going around and accuse people of making bad designs, it<br/>&gt; &gt;would be much better to improve the documentation for POE, so that said<br/>&gt; &gt;people don&#39;t have to go around and start guessing...<br/><br/>&gt; I don&#39;t appreciate your vague, negative comments about the <br/>&gt; documentation. Please describe problems in a useful way, or your <br/>&gt; expectation that they be fixed is unreasonable.<br/><br/>I did, in a long document that you admit having read already. If you don&#39;t<br/>find the comments useful, thats your problem - you could aks me to clarify<br/>them, for example.<br/><br/>_I_ don&#39;t appreciate your continuous implications that my comemnts were in<br/>some way flawed without every mentioning a single piece of evidence.<br/><br/>&gt; You seem to be saying that your design for AnyEvent::Impl::POE is <br/>&gt; based on guesswork.<br/><br/>Yes.<br/><br/>&gt; If so, I overestimated your knowledge of POE based on your<br/>&gt; documentation.<br/><br/>I have no idea how you estimate my knowledge. I also fail to see what my<br/>person has to do with anything.<br/><br/>&gt; Therefore, please consider the chance that you may know less about POE<br/>&gt; than your documentation implies.<br/><br/>If there is any meaning in this sentence, it escapes me. I quited examples<br/>form the documentation and explained all my arguments. It doesn&#39;t matter how<br/>much I know or imply to know, as I *explain* the reasons behind what I said.<br/><br/>That is in stark contrast to you - you only ever imply the documentation<br/>is rude, the module is fundamentally flawed, the comments are not useful<br/>etc., without ever trying to solve the problems with POE that lead to this<br/>design and the comments, and which are explained clearly.<br/><br/>&gt; &gt;Oh, and while you fix the docs, could you fix the other bugs as well<br/>&gt; <br/>&gt; I certainly can, but you&#39;ll need to describe them in a useful way <br/><br/>Done a long time ago and given to you. It might not be in a form that you<br/>like, but it is doubtless that they are useful.<br/><br/>&gt; &gt;(the race condition with sigchld is really annoying,<br/>&gt; <br/>&gt; Please describe the race condition in a useful way, so that I can <br/>&gt; investigate and possibly fix it.<br/><br/>Again the red herring &quot;useful&quot; - it obviously was useful enough for other<br/>people to understand the issue. The problem is that rgeistering a watcher<br/>after the child process already exited causes POE to introduce a delay in<br/>reapign the child (it does seem to do polling to do so, and seems to do so<br/>once per second, so the delay is at most a second, still, thats a pretty<br/>long time).<br/><br/>&gt; POE checks for child processes between calls to application code. If <br/>&gt; you fork your process and set sig_child() in the same event handler, <br/>&gt; POE won&#39;t be able to call waitpid() between them. If this is the race <br/>&gt; condition you mean, then it simply shouldn&#39;t be possible.<br/><br/>The race condition is quite simple:<br/><br/>1. fork<br/>2. child exits<br/>3. parents gets sigchld (but no sigchld handler is registered yet)<br/>4. sigchld watchers gets created<br/>[time passes, POE select&#39;s many times without noticing the child exit]<br/>5. POE eventually waitpids and finally detetcs the child<br/><br/>&gt; On the other hand, I haven&#39;t actually documented this behavior. It <br/>&gt; hadn&#39;t occurred to me because all my programs follow the reliable <br/>&gt; pattern.<br/><br/>I have no clue what you mean, but POE ahs to support it, just as with any<br/>other event loop - you cnanot tregister a child handler BEFORE you fork<br/>because you don&#39;t know the pid. You cannot guarantee that the child exits<br/>only afetr you registered the watcher, so POE has to deal with it already<br/>having exited.<br/><br/>AnyEvent and EV certainly deal with this issue cirretcly and don&#39;t miss<br/>the child exit.<br/><br/>&gt; &quot;Programs that wish to reliably reap child processes should be sure to <br/>&gt; call sig_child() before returning from the event handler that forked <br/>&gt; the process. Otherwise POE::Kernel may have an opportunity to call <br/>&gt; waitpid() before an appropriate event watcher has been registered.&quot;<br/><br/>No, it is a race in POE, not something the application can do anything<br/>about.<br/><br/>&gt; In the event that you&#39;ve found an actual bug, I regret that your <br/>&gt; description of the problem is not useful.<br/><br/>Well, I can declare anything I want &quot;not useful&quot; - if you are incapable of<br/>understanding, you should ask - I don&#39;t know how wlel your knowledge is<br/>w.r.t. to process handling on unix, and I cannot write full novels and<br/>programming manuals just in case I need to cover something you don&#39;t<br/>understand.<br/><br/>&gt; &lt;purl&gt; Look buddy, doesn&#39;t work is a strong statement. Does it sit on <br/><br/>&quot;doesn&#39;t work&quot; is certainly not how I described it.<br/><br/>&gt; &gt;and the nag messages are as well).<br/>&gt; <br/>&gt; I understand from your documentation that you dislike the &quot;ugly&quot; &quot;nag&quot; <br/>&gt; messages. I&#39;m sorry, but I cannot help you there. They were added as <br/>&gt; the result of useful feedback from other users. And contrary to your <br/>&gt; documentation, they can be silenced.<br/><br/>Possible, but it is not documented (yes, run silences them, but it has<br/>other undesirable effects as well, which is documented by AnyEvent&#39;s<br/>adaptor module).<br/><br/>&gt; The &quot;run() method was never called&quot; message can be silenced by calling <br/>&gt; run(). Not all applications require run(). But if you call it <br/>&gt; without any POE::Session instances, it will return immediately and <br/>&gt; satisfy POE::Kernel.<br/><br/>This is impossible it guarentee from within AnyEvent.<br/><br/>So there is no way to silence just the message.<br/><br/>&gt; While this does not:<br/>&gt; <br/>&gt; perl -wle &#39;use POE; POE::Kernel-&gt;run; POE::Session- <br/>&gt; &gt;create(inline_states =&gt; { _start =&gt; sub{} });&#39;<br/><br/>As I said, for design reasons, Anyevent doesn&#39;t enforce itself on its<br/>users, so the requirement to call -&gt;run is not implementable.<br/><br/>AnyEvent::Impl::POE already invokes the run workaround in its manpage, and<br/>why it is undesirable. This puts an unecessary burden on the user, and is<br/>certainly an issue.<br/><br/>&gt; I hadn&#39;t considered to document the technique because it seemed <br/>&gt; obvious to me.<br/><br/>It is obvious to me. But there is now ay to do that from within a module:<br/>a module has no control over when it was loaded.<br/><br/>It is just one of the many small design issues (some of which I<br/>documented) that make it very hard to use POE in a generic way.<br/><br/>I don&#39;t claim more, I don&#39;t claim less.<br/><br/>&gt; obvious to me than are actually obvious to the average user. You <br/>&gt; should probably call them to my attention if you&#39;d like them to be <br/>&gt; documented.<br/><br/>I only need a way to silence them withotu potentially freezing the<br/>program, clearing the event queue, stopping running sessions etc.<br/><br/>&gt; Speaking of which, I added this to the docs. Please let me know how/ <br/>&gt; if I can improve it:<br/><br/>No amount of documentation can improve this, it is a problem within the<br/>POE code.<br/><br/>&gt; You complain about a message that occurs when a program leaks a child <br/>&gt; process. Programs that leak processes are broken in a way that is <br/>&gt; difficult to detect without the warning. In extreme cases, process <br/>&gt; leakage can quietly strangle a machine to death.<br/><br/>No, I complain about the emssage complaining about POE reaping a child. No<br/>leak is involved anywhere, and nothign will &quot;quietly&quot; &quot;strangle&quot; anything<br/>to death.<br/><br/>&gt; POE can detect this silent but deadly condition.<br/><br/>There is nothing deadly about it.<br/><br/>&gt; If you receive this message, it can be silenced by fixing the process <br/>&gt; leak.<br/><br/>... which is nonexistant.<br/><br/>&gt; &gt;Not sure why it would be a courtesy to me, do you have anything to <br/>&gt; &gt;hide<br/>&gt; &gt;or do you want to insult me even more in private so nobody sees your <br/>&gt; &gt;real<br/>&gt; &gt;self or something? (just guessing... :)<br/>&gt; <br/>&gt; Wow, you really do expect the worst from me. I don&#39;t know where that <br/>&gt; came from.<br/><br/>I expect you to back up your statements you made publicly (and in<br/>private). As I told you before, it *is* bad (or worse) to make statements<br/>without backing them up.<br/><br/>&gt; The courtesy to you would be that I brought the issues to you <br/>&gt; directly.<br/><br/>It would be, if you had done that. But in private you just insulted<br/>me more directly, but despite reqpeatedly askign you how to solve the<br/>probelms with session lifetime, you never came up with any evidence.<br/><br/>&gt; I could post them somewhere public and unexpected and wait <br/>&gt; for you to find them, but that&#39;s just rude.<br/><br/>Thats much better then making public statements and not tellign anybody<br/>about it, especially not me.<br/><br/>&gt; Likewise, posting long, limited-interest e-mail to a public <br/>&gt; distribution list is a violation of common etiquette. To those who <br/>&gt; are still reading, I&#39;m sorry.<br/><br/>Discussing various event loops for perl is certainly within the charter of<br/>this mailing list.<br/><br/>Also note that you started it - I backed up all my claims with evidence<br/>(even if it is wrong, one can at least verify my claims).<br/><br/>All you did is make broad statements such as &quot;your module has a broken<br/>design&quot; without ever explaining how to work around the problems I<br/>documented that caused this allegedly &quot;broken design&quot;.<br/><br/>&gt; I kind of thought those points would be obvious.<br/><br/>It is possible that everything is obvious to you, but if you make broad<br/>statements like the above you *need to back them up with evidence*.<br/><br/>&gt; If you still insist on doing this publicly, please indicate your <br/>&gt; intent by posting your documentation for AnyEvent::Impl::POE to the <br/>&gt; mailing list (new thread, please).<br/><br/>The docoumentation always was publicly available from the AnyEvent site, also<br/>where the benchmakr results have bene published.<br/><br/>Anyevent 3.3 has now been released with the POE module, though, so it should<br/>not be a problem to find it anymore, it is on CPAN.<br/><br/>&gt; OMG, we agree on something! The end times are here:<br/><br/>sorry?<br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1117.html Mon, 28 Apr 2008 03:24:37 +0000 Re: benchmarking various event loops with and without anyevent by Rocco Caputo On Apr 28, 2008, at 03:21, Marc Lehmann wrote:<br/>&gt; On Sat, Apr 26, 2008 at 08:13:27AM -0400, Rocco Caputo &lt;rcaputo@pobox.com <br/>&gt; &gt; wrote:<br/>&gt;&gt; each event watcher. Anyone who knows POE can tell you this is one of<br/>&gt;&gt; the least efficient designs possible. In fact, this design is worse<br/>&gt;&gt; than the average for first-time POE users.<br/>&gt;<br/>&gt; [He then called my model fundamentally broken in private mail and the<br/>&gt; documentation rude and unprofessional, without bringing up any <br/>&gt; evidence]<br/><br/>Dear perl-loop@perl.org, and anyone reading this in the archives.<br/><br/>I apologize for my part in this unfolding thread. As Marc mentions, I <br/>have been trying to take it to private e-mail. However I feel that <br/>Marc has misrepresented to the list what I said to him in private. At <br/>this point, it&#39;s easier for me to repost what I actually said rather <br/>than paraphrase it.<br/><br/>Again, I&#39;m sorry you had to be involved.<br/><br/>-- <br/>Rocco Caputo - rcaputo@pobox.com<br/><br/>Begin forwarded message:<br/>&gt; From: Rocco Caputo &lt;rcaputo@pobox.com&gt;<br/>&gt; Date: April 27, 2008 23:29:18 EDT<br/>&gt; To: Marc Lehmann &lt;schmorp@schmorp.de&gt;<br/>&gt; Subject: Re: benchmarking various event loops with and without <br/>&gt; anyevent<br/>&gt;<br/>&gt; On Apr 27, 2008, at 01:53, Marc Lehmann wrote:<br/>&gt;<br/>&gt;&gt; On Sun, Apr 27, 2008 at 01:15:49AM -0400, Rocco Caputo &lt;rcaputo@pobox.com <br/>&gt;&gt; &gt; wrote:<br/>&gt;&gt;&gt; I have read your code and documentation for AnyEvent::Impl::POE. <br/>&gt;&gt;&gt; Your<br/>&gt;&gt;&gt; module&#39;s design is fundamentally broken, and your code is probably<br/>&gt;&gt;&gt; more to blame than POE.<br/>&gt;&gt;<br/>&gt;&gt; Oh, btw, be careful with such strong idioms such as &quot;fundemantally <br/>&gt;&gt; broken&quot;:<br/>&gt;&gt; so far, there is no evidence that it is broken at all, only <br/>&gt;&gt; inefficient.<br/>&gt;&gt;<br/>&gt;&gt; (If you think it really is fundamentally _broken_ then you better <br/>&gt;&gt; back up<br/>&gt;&gt; your statements).<br/>&gt;<br/>&gt; I hope to show that I intended no offense.<br/>&gt;<br/>&gt; Reasonable scalability (CPU and memory) seems to be one of <br/>&gt; AnyEvent&#39;s design goals. I base this impression on the fact that <br/>&gt; you&#39;re benchmarking your code in terms of speed and size. <br/>&gt; &quot;Reasonable&quot; is subject to interpretation, but I think we agree that <br/>&gt; AnyEvent::Impl::POE is neither as fast nor as small as it should be.<br/>&gt;<br/>&gt; Therefore, while AnyEvent::Impl::POE operates correctly, it does not <br/>&gt; fulfill some of AnyEvent&#39;s design goals.<br/>&gt;<br/>&gt; AnyEvent::Impl::POE&#39;s greatest inefficiencies stem from one <br/>&gt; fundamental design choice: the 1:1 relationship between watcher <br/>&gt; instances and POE::Session instances. In your own words: &quot;AnyEvent <br/>&gt; has to create one POE::Session per event watcher, which is immensely <br/>&gt; slow and makes watchers very large.&quot;<br/>&gt;<br/>&gt; One point of contention may be whether this is a design or <br/>&gt; implementation flaw. The problem is inherent in the way one class <br/>&gt; (AnyEvent::Impl::POE) interacts with another (POE::Session). Class <br/>&gt; interaction is a software design issue. It can be modeled in <br/>&gt; software design languages such as UML. Re-implementing the same <br/>&gt; entity relationship more efficiently, or in a faster language such <br/>&gt; as C, would not resolve the scalability problem.<br/>&gt;<br/>&gt; Therefore, AnyEvent::Impl::POE is flawed in design rather than <br/>&gt; implementation.<br/>&gt;<br/>&gt; Therefore, AnyEvent::Impl::POE&#39;s design prevents it from meeting <br/>&gt; some of AnyEvent&#39;s design goals.<br/>&gt;<br/>&gt; Therefore, AnyEvent::Impl::POE&#39;s design is broken.<br/>&gt;<br/>&gt; Unfortunately most of AnyEvent::Impl::POE&#39;s design stems from its <br/>&gt; flawed interaction with POE::Session. We should not need to change <br/>&gt; AnyEvent::Impl::POE&#39;s public interface, but we will need to rethink <br/>&gt; and revise nearly all aspects of its interaction with POE.<br/>&gt;<br/>&gt; Therefore, AnyEvent::Impl::POE&#39;s design flaw is a fundamental one.<br/>&gt;<br/>&gt; Therefore, AnyEvent::Impl::POE&#39;s design is fundamentally broken.<br/>&gt;<br/>&gt;&gt; Again, let me repeat that empty insults that obviously are founded by<br/>&gt;&gt; paranoia will not have any positive effect on your standing with me <br/>&gt;&gt; (I<br/>&gt;&gt; mean, I won&#39;t hate you or anything, but you make yourself an idiot <br/>&gt;&gt; in my<br/>&gt;&gt; eyes very quickly by repeatedly not beinging up any evidence...).<br/>&gt;&gt;<br/>&gt;&gt; Of course, I understand that if you mistook my comments about POE <br/>&gt;&gt; as rude,<br/>&gt;&gt; there is a natural tendency to &quot;insult back&quot;.<br/>&gt;<br/>&gt;<br/>&gt; I hope I have shown reasonable evidence that my assertion is neither <br/>&gt; empty nor intrinsically insulting. Without the intent to insult, <br/>&gt; there can be no intent to &quot;insult back&quot;. In the end, any offense <br/>&gt; you have taken may be of your own manufacture. Could there be <br/>&gt; cultural differences to overcome?<br/>&gt;<br/>&gt; In this light, your assertion of my paranoia is unfounded, unjust <br/>&gt; and offensive. Your view that I&#39;m acting like an idiot is no <br/>&gt; better. You are of course entitled to your opinions, but those two <br/>&gt; are not appropriate for polite conversation.<br/>&gt;<br/>&gt; ...<br/>&gt;<br/>&gt; I&#39;m sorry that I haven&#39;t responded promptly to your e-mail. I get <br/>&gt; the impression that you expect the worst from me, so I feel the need <br/>&gt; to choose my words in a slow and painful (and often futile) effort <br/>&gt; to minimize being misunderstood. As a result, I cannot write to you <br/>&gt; as often as I would like. Nor have I had the opportunity to work <br/>&gt; with you on the module in question (something I would much rather be <br/>&gt; doing).<br/>&gt;<br/>&gt; I hope we can reach a mutual understanding, if only so that we may <br/>&gt; correspond and collaborate more effectively.<br/>&gt;<br/>&gt; Until next time,<br/>&gt;<br/>&gt; -- <br/>&gt; Rocco Caputo - rcaputo@pobox.com<br/><br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1116.html Mon, 28 Apr 2008 02:21:09 +0000 Re: benchmarking various event loops with and without anyevent by Rocco Caputo On Apr 27, 2008, at 00:56, Marc Lehmann wrote:<br/>&gt; On Sat, Apr 26, 2008 at 08:13:27AM -0400, Rocco Caputo &lt;rcaputo@pobox.com <br/>&gt; &gt; wrote:<br/>&gt;&gt; each event watcher. Anyone who knows POE can tell you this is one of<br/>&gt;&gt; the least efficient designs possible.<br/>&gt;<br/>&gt; It is the only design that I could get working, even after <br/>&gt; consulting a<br/>&gt; few people and implementing some workarounds for the bugs in POE.<br/>&gt;<br/>&gt; In any case, you have to consider that most people on this planet<br/>&gt; don&#39;t know POE, and even if, they don&#39;t know it that well. Since the<br/>&gt; documentation for POE is in such a bad state, thats the obvious way <br/>&gt; to fix<br/>&gt; that.<br/><br/>Most people on the planet don&#39;t know Perl, or even how to program a <br/>computer. No amount of documentation will help them. :)<br/><br/>In the future, you may wish to include me on your list of people to <br/>consult about designing applications for POE. I may known a thing or <br/>two about the topic. :)<br/><br/>Are you aware that I&#39;m gradually rewriting POE&#39;s documentation? If <br/>you could describe what you don&#39;t like in a useful way, I may be able <br/>to do something about it.<br/><br/>&gt;&gt; In fact, this design is worse than the average for first-time POE <br/>&gt;&gt; users.<br/>&gt;<br/>&gt; If a better design is possible, it is not known to me, and you haven&#39;t<br/>&gt; suggested one either, so talk is cheap. I&#39;d be happy to get a more<br/>&gt; efficient design for POE but nobody could come up with one that also<br/>&gt; worked reliably through multiple iterations of run and also does not <br/>&gt; keep<br/>&gt; the POE kernel from returning.<br/><br/>I would love to have the opportunity to suggest a different design, <br/>but most of my discretionary time is spent addressing the constant <br/>misunderstandings between us. If we can first resolve them, I&#39;ll have <br/>that much more time to work on the design.<br/><br/>Obviously I cannot expect you to know everything about POE. Likewise, <br/>you cannot expect me to magically know when you started writing <br/>AnyEvent::Impl::POE. Even if you announced it somewhere, I may not <br/>have been looking. The first I heard of it was here, when you <br/>announced your benchmarks.<br/><br/>In general, if you need someone&#39;s attention online, the most effective <br/>and polite way is to contact them directly. If you did contact me <br/>about this, then I&#39;m sorry that I missed it. Are you sure your <br/>message wasn&#39;t lost in transit?<br/><br/>As for the design:<br/><br/>First-time POE users tend to design programs where the number of <br/>sessions scales linearly with the number of objects that handle <br/>events. If S(1) is the total overhead imposed by a single session, <br/>then S(N) is the overhead imposed by the average na&iuml;ve POE user. N is <br/>the number of objects handling events.<br/><br/>AnyEvent::Impl::POE creates a new POE::Session for every event <br/>watcher. It&#39;s not uncommon for an object to use more than one event <br/>watcher (I/O and timeout, for example). So we can model the session <br/>overhead in an AnyEvent::Impl::POE program as S(N*M), where N is the <br/>number of objects handling events, and M is the average number of <br/>event watchers per object.<br/><br/>Assuming that N is the same between the equivalent POE and <br/>AnyEvent::Impl::POE program:<br/><br/>S(N*M) &gt; S(N) for M &gt; 1.<br/><br/>QED :P<br/><br/>&gt; If a better design *is* possible (which I don&#39;t really doubt), then it<br/>&gt; needs to be vastly more complex, or it needs some non-obvious trick. <br/>&gt; I can<br/>&gt; only imagine making some very complex on-demand instantiating and re- <br/>&gt; check<br/>&gt; wether the session still exists on each watcher creation.<br/><br/>Your imagination comes up with such incredible things. Don&#39;t lose <br/>that. :)<br/><br/>The &quot;trick&quot; is to minimize the number of sessions used. Your <br/>benchmarks and comments in your documentation implied that you knew <br/>that sessions imposed overhead. I wrongly assumed the solution would <br/>be obvious.<br/><br/>In your case, I would create a single persistent POE::Session instance <br/>that serviced all the watchers. The watchers themselves would be <br/>small proxies that controlled POE::Kernel watchers within that <br/>session&#39;s context.<br/><br/>I use this design in POE::Stage. If you&#39;re not averse to looking at <br/>experimental code, you can find it on the CPAN. It also does a lot of <br/>other, unrelated things, so you may have difficulty separating the <br/>magic you need from the voodoo you don&#39;t. Comments are welcome, if <br/>they&#39;re useful.<br/><br/>&gt; (It is possible that I was fooled by the docs as well, so if there <br/>&gt; is a<br/>&gt; better way, it likely isn&#39;t documented, so who could blame me).<br/><br/>I won&#39;t blame you. But I will point out that your documentation says <br/>you&#39;re already familiar with using undocumented POE features. :)<br/><br/>&gt; Instead of going around and accuse people of making bad designs, it <br/>&gt; would<br/>&gt; be much better to improve the documentation for POE, so that said <br/>&gt; people<br/>&gt; don&#39;t have to go around and start guessing...<br/><br/>I don&#39;t appreciate your vague, negative comments about the <br/>documentation. Please describe problems in a useful way, or your <br/>expectation that they be fixed is unreasonable.<br/><br/>You seem to be saying that your design for AnyEvent::Impl::POE is <br/>based on guesswork. If so, I overestimated your knowledge of POE <br/>based on your documentation. Therefore, please consider the chance <br/>that you may know less about POE than your documentation implies.<br/><br/>&gt; Oh, and while you fix the docs, could you fix the other bugs as well<br/><br/>I certainly can, but you&#39;ll need to describe them in a useful way <br/>first. http://search.yahoo.com/search?p=useful+bug+reports seems to <br/>link to good tips.<br/><br/>And please post them to POE&#39;s rt.cpan.org queue. The Perl community <br/>has been kind enough to establish a convenient, central place to <br/>report problems with CPAN distributions. It would be most cooperative <br/>of you to use it.<br/><br/>&gt; (the race condition with sigchld is really annoying,<br/><br/><br/>Please describe the race condition in a useful way, so that I can <br/>investigate and possibly fix it.<br/><br/>POE checks for child processes between calls to application code. If <br/>you fork your process and set sig_child() in the same event handler, <br/>POE won&#39;t be able to call waitpid() between them. If this is the race <br/>condition you mean, then it simply shouldn&#39;t be possible.<br/><br/>On the other hand, I haven&#39;t actually documented this behavior. It <br/>hadn&#39;t occurred to me because all my programs follow the reliable <br/>pattern. Based on your feedback, I added this to the description of <br/>sig_child(). Please let me know how/if I can improve it:<br/><br/>&quot;Programs that wish to reliably reap child processes should be sure to <br/>call sig_child() before returning from the event handler that forked <br/>the process. Otherwise POE::Kernel may have an opportunity to call <br/>waitpid() before an appropriate event watcher has been registered.&quot;<br/><br/>In the event that you&#39;ve found an actual bug, I regret that your <br/>description of the problem is not useful. As we say in IRC:<br/><br/>&lt;purl&gt; Look buddy, doesn&#39;t work is a strong statement. Does it sit on <br/>the couch all day? Is it making faces at you? Does it want more money? <br/>Is it sleeping with your girlfriend? Please be specific!<br/><br/>&gt; and the nag messages are as well).<br/><br/>I understand from your documentation that you dislike the &quot;ugly&quot; &quot;nag&quot; <br/>messages. I&#39;m sorry, but I cannot help you there. They were added as <br/>the result of useful feedback from other users. And contrary to your <br/>documentation, they can be silenced.<br/><br/>The &quot;run() method was never called&quot; message can be silenced by calling <br/>run(). Not all applications require run(). But if you call it <br/>without any POE::Session instances, it will return immediately and <br/>satisfy POE::Kernel.<br/><br/>For example, this generates the warning:<br/><br/>perl -wle &#39;use POE; POE::Session-&gt;create(inline_states =&gt; { _start =&gt; <br/>sub{} });&#39;<br/><br/>While this does not:<br/><br/>perl -wle &#39;use POE; POE::Kernel-&gt;run; POE::Session- <br/> &gt;create(inline_states =&gt; { _start =&gt; sub{} });&#39;<br/><br/>I hadn&#39;t considered to document the technique because it seemed <br/>obvious to me. By now I hope it&#39;s clear that a lot more things seem <br/>obvious to me than are actually obvious to the average user. You <br/>should probably call them to my attention if you&#39;d like them to be <br/>documented.<br/><br/>Speaking of which, I added this to the docs. Please let me know how/ <br/>if I can improve it:<br/><br/>&quot;POE::Kernel will print a strong message if a program creates sessions <br/>but fails to call run(). If the lack of a run() call is deliberate, <br/>you can avoid the message by calling it before creating a session. <br/>run() at that point will return immediately, and POE::Kernel will be <br/>satisfied.&quot;<br/><br/>...<br/><br/>You complain about a message that occurs when a program leaks a child <br/>process. Programs that leak processes are broken in a way that is <br/>difficult to detect without the warning. In extreme cases, process <br/>leakage can quietly strangle a machine to death.<br/><br/>POE can detect this silent but deadly condition. It notifies users <br/>out of courtesy to them, and also because I was tired of handling &quot;POE <br/>crashed my machine!&quot; reports. In this case, the one who smelled it <br/>did not deal it.<br/><br/>If you receive this message, it can be silenced by fixing the process <br/>leak.<br/><br/>&gt;&gt; I have specific issues with your docs. As a courtesy to you and the<br/>&gt;&gt; list, I&#39;ll send them to you directly.<br/>&gt;<br/>&gt; Not sure why it would be a courtesy to me, do you have anything to <br/>&gt; hide<br/>&gt; or do you want to insult me even more in private so nobody sees your <br/>&gt; real<br/>&gt; self or something? (just guessing... :)<br/><br/>Wow, you really do expect the worst from me. I don&#39;t know where that <br/>came from.<br/><br/>The courtesy to you would be that I brought the issues to you <br/>directly. I could post them somewhere public and unexpected and wait <br/>for you to find them, but that&#39;s just rude.<br/><br/>Likewise, posting long, limited-interest e-mail to a public <br/>distribution list is a violation of common etiquette. To those who <br/>are still reading, I&#39;m sorry.<br/><br/>I kind of thought those points would be obvious.<br/><br/>If you still insist on doing this publicly, please indicate your <br/>intent by posting your documentation for AnyEvent::Impl::POE to the <br/>mailing list (new thread, please). That will make it easier for me to <br/>respond. For the record, I still think this is a bad idea.<br/><br/>&gt; I do fix my bugs and am open to suggestions and improvements. But<br/>&gt; correctness comes first, performance second.<br/><br/><br/>OMG, we agree on something! The end times are here:<br/><br/>-- <br/>Rocco Caputo - rcaputo@pobox.com http://www.nntp.perl.org/group/perl.loop/2008/04/msg1115.html Mon, 28 Apr 2008 01:37:00 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Sat, Apr 26, 2008 at 08:13:27AM -0400, Rocco Caputo &lt;rcaputo@pobox.com&gt; wrote:<br/>&gt; each event watcher. Anyone who knows POE can tell you this is one of <br/>&gt; the least efficient designs possible. In fact, this design is worse <br/>&gt; than the average for first-time POE users.<br/><br/>[He then called my model fundamentally broken in private mail and the<br/>documentation rude and unprofessional, without bringing up any evidence]<br/><br/>In all fairness, I want to point out that, after _multiple_ rounds of<br/>longish e-mail exchanges, Rocco Caputo could not solve the problems that<br/>forced AnyEvent to use this design, nor did he enlighten me on how to work<br/>around the specific problems that I mentioned to him that forced this<br/>design decision(*).<br/><br/>He did not come up with any further evidence for a problem, either (just<br/>repeatedly stating that the design is broken. The only argument he brought<br/>up was: one of your design goals is to be reasonably efficient, POE does<br/>not do it reasonably efficient, so your design is broken, which is an<br/>outright absurd logic).<br/><br/>In fact, it seems his problem is indeed the AnyEvent API and not the<br/>interface module to POE, i.e. the &quot;broken&quot; means I should not provide<br/>events in the form AnyEvent does, which is of course counterproductive to<br/>the goal of AnyEvent of being compatible to multiple event loops (I can&#39;t<br/>provide different APIs to different event loops...).<br/><br/>So I conclude that even the POE author is unable to provide a (strongly)<br/>more efficient approach, which, according to his own words, would make him<br/>worse then the average first-time POE user.<br/><br/>This is absurd, so I conclude that the original claim has been disproven.<br/><br/>(And yes, I did ask multiple times to come up with how to better design<br/>the interface to POE, or how to solve the lifetime-issues with POE).<br/><br/>(*) the specific problems are (taken directly from my mail to rocco):<br/><br/>- the session must not go away, or there must be an easy way to recreate<br/> it when the kernel kills it.<br/>- the session itself must not keep the kernel &quot;alive&quot;/running (preferably<br/> without going away).<br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1114.html Mon, 28 Apr 2008 00:22:12 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Sat, Apr 26, 2008 at 08:13:27AM -0400, Rocco Caputo &lt;rcaputo@pobox.com&gt; wrote:<br/>&gt; each event watcher. Anyone who knows POE can tell you this is one of <br/>&gt; the least efficient designs possible.<br/><br/>It is the only design that I could get working, even after consulting a<br/>few people and implementing some workarounds for the bugs in POE.<br/><br/>In any case, you have to consider that most people on this planet<br/>don&#39;t know POE, and even if, they don&#39;t know it that well. Since the<br/>documentation for POE is in such a bad state, thats the obvious way to fix<br/>that.<br/><br/>&gt; In fact, this design is worse than the average for first-time POE users.<br/><br/>If a better design is possible, it is not known to me, and you haven&#39;t<br/>suggested one either, so talk is cheap. I&#39;d be happy to get a more<br/>efficient design for POE but nobody could come up with one that also<br/>worked reliably through multiple iterations of run and also does not keep<br/>the POE kernel from returning.<br/><br/>If a better design *is* possible (which I don&#39;t really doubt), then it<br/>needs to be vastly more complex, or it needs some non-obvious trick. I can<br/>only imagine making some very complex on-demand instantiating and re-check<br/>wether the session still exists on each watcher creation.<br/><br/>(It is possible that I was fooled by the docs as well, so if there is a<br/>better way, it likely isn&#39;t documented, so who could blame me).<br/><br/>Instead of going around and accuse people of making bad designs, it would<br/>be much better to improve the documentation for POE, so that said people<br/>don&#39;t have to go around and start guessing...<br/><br/>Oh, and while you fix the docs, could you fix the other bugs as well (the<br/>race condition with sigchld is really annoying, and the nag messages are<br/>as well).<br/><br/>&gt; I have specific issues with your docs. As a courtesy to you and the <br/>&gt; list, I&#39;ll send them to you directly.<br/><br/>Not sure why it would be a courtesy to me, do you have anything to hide<br/>or do you want to insult me even more in private so nobody sees your real<br/>self or something? (just guessing... :)<br/><br/>I do fix my bugs and am open to suggestions and improvements. But<br/>correctness comes first, performance second.<br/><br/>Greetings,<br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1113.html Sat, 26 Apr 2008 21:56:31 +0000 Re: benchmarking various event loops with and without anyevent by Rocco Caputo On Apr 25, 2008, at 22:46, Marc Lehmann wrote:<br/>&gt;<br/>&gt; The next release of AnyEvent contains support for a few more <br/>&gt; &quot;backends&quot;,<br/>&gt; notably POE, so AnyEvent is now by definition compatible to POE <br/>&gt; (before it<br/>&gt; was only compatible when using an even loop used by POE, such as <br/>&gt; Event or<br/>&gt; EV that could be shared).<br/><br/>&gt; The results were mostly as expected, with EV leading and POE being<br/>&gt; abysmal.<br/><br/>It&#39;s no wonder that AnyEvent::Impl::POE runs so slowly. According to <br/>your documentation, you designed it to use a separate POE::Session for <br/>each event watcher. Anyone who knows POE can tell you this is one of <br/>the least efficient designs possible. In fact, this design is worse <br/>than the average for first-time POE users.<br/><br/>On the bright side, you could still have done worse. You could have <br/>instantiated and destroyed a POE::Session for each event. Perhaps <br/>you&#39;re saving that for a future release. :)<br/><br/>I have specific issues with your docs. As a courtesy to you and the <br/>list, I&#39;ll send them to you directly.<br/><br/>-- <br/>Rocco Caputo - rcaputo@pobox.com<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1112.html Sat, 26 Apr 2008 05:13:43 +0000 Re: benchmarking various event loops with and without anyevent by Uri Guttman &gt;&gt;&gt;&gt;&gt; &quot;ML&quot; == Marc Lehmann &lt;schmorp@schmorp.de&gt; writes:<br/><br/> ML&gt; The surprising one was the pure perl implementation, which was quite on<br/> ML&gt; par with C-based event loops such as Event or Glib. I did expect the pure<br/> ML&gt; perl implementatioon to be at least a factor of three slower than Event or<br/> ML&gt; Glib.<br/><br/> ML&gt; As the pure perl loop wasn&#39;t written with high performance in mind, this<br/> ML&gt; prompted me to optimise it for some important cases (mostly to get rid of<br/> ML&gt; the O(n&sup2;) degenerate cases and improving the select bitmask parsing for<br/> ML&gt; the sparse case).<br/><br/>check out stem&#39;s pure perl event loop. there are examples in the<br/>/sessions dir on how to use that directly without the rest of the<br/>modules. it does things in a different direction and doesn&#39;t scan<br/>select&#39;s bit masks but instead it scans the interesting handles and see<br/>whether their bits are set. it should exhibit good behavior under growth<br/>as all the data are managed in hashes.<br/><br/> ML&gt; I then made a second benchmark, designed not to measure anyevent overhead,<br/> ML&gt; but to measure real-world performance of a socket server.<br/><br/>and that /sessions code also shows use of the asyncio module. if you can<br/>benchmark that i would be interested in the results. <br/><br/> ML&gt; The result is that the pure perl event loop used as fallback in AnyEvent<br/> ML&gt; single-handedly beats Glib by a large margin, and even event by a factor<br/> ML&gt; of two.<br/><br/> ML&gt; For small servers, the overhead introduced by running a lot of perl<br/> ML&gt; opcodes per iteration dominates, however, reflected in the last benchmark.<br/><br/>in a heavily loaded server most of the work in in the i/o and should<br/>overwhelm the event loop itself. that is the whole purpose of event<br/>loops as we all know here. <br/><br/> ML&gt; However, the net result is that the pure perl event loop performs<br/> ML&gt; better than almost all other event loops (EV being the only exception)<br/> ML&gt; ins erious/medium-sized cases, while I originally expected it to fail<br/> ML&gt; completely w.r.t. performance and being only usable as a workaround when<br/> ML&gt; no &quot;better&quot; event module is installed.<br/><br/>i don&#39;t find that surprising. perl&#39;s i/o is decent and as i said above,<br/>a loaded server is doing mostly i/o. <br/><br/> ML&gt; All the benchmark data and explanations can be found here:<br/><br/> ML&gt; http://pod.tst.eu/http://cvs.schmorp.de/AnyEvent/lib/AnyEvent.pm#BENCHMARKS<br/><br/> ML&gt; The code is not yet released and likely still buggy (the question is<br/> ML&gt; whether any bugs affect the benchmark results). It is only available via<br/> ML&gt; CVS: http://software.schmorp.de/pkg/AnyEvent<br/><br/>i will take a gander and see if i can play with it and add stem&#39;s loop<br/>to it. if you want to work on this with me, i wouldn&#39;t mind the help.<br/><br/>thanx,<br/><br/>uri<br/><br/>-- <br/>Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --<br/>----- Perl Code Review , Architecture, Development, Training, Support ------<br/>--------- Free Perl Training --- http://perlhunter.com/college.html ---------<br/>--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1111.html Sat, 26 Apr 2008 02:34:46 +0000 Re: benchmarking various event loops with and without anyevent by Uri Guttman &gt;&gt;&gt;&gt;&gt; &quot;ML&quot; == Marc Lehmann &lt;schmorp@schmorp.de&gt; writes:<br/><br/> ML&gt; On Fri, Apr 25, 2008 at 11:40:03PM -0400, Uri Guttman &lt;uri@stemsystems.com&gt; wrote:<br/> &gt;&gt; check out stem&#39;s pure perl event loop. there are examples in the<br/><br/> ML&gt; Maybe I&#39;ll provide a backend for stem.<br/><br/>actually it makes more sense to me to wrap anyevent in stem. it already<br/>has several event wrappers (pure perl, event.pm and tk) and wrapping is<br/>very easy to do. not much different than the code i see in anyevent.<br/><br/> &gt;&gt; modules. it does things in a different direction and doesn&#39;t scan<br/> &gt;&gt; select&#39;s bit masks but instead it scans the interesting handles and see<br/> &gt;&gt; whether their bits are set. it should exhibit good behavior under growth<br/> &gt;&gt; as all the data are managed in hashes.<br/><br/> ML&gt; That is exactly as the anyevent perl backend did in the previous<br/> ML&gt; version. I don&#39;t see how that should exhibit good behaviour - file<br/> ML&gt; descristpors are small integers, so hashes only add overhead over arrays,<br/> ML&gt; and checking every file descriptor that way is much slower than scanning<br/> ML&gt; the bitmask.<br/><br/> ML&gt; Especially in the important case of many handles/few active ones, an approach<br/> ML&gt; of &quot;scan all handles&quot; is very slow.<br/><br/>my code doesn&#39;t scan all handle, but scan all writeable events to see if<br/>their handle bits are set. descriptors increment and can cause bloat of<br/>the array if you have many in use (and not all of them in the event loop).<br/><br/> ML&gt; (The benchmarks reflect this, you could try with an older anyevent<br/> ML&gt; release where we just check the keys of the hash storing fd<br/> ML&gt; information: performance is much lower).<br/><br/> ML&gt; I then made a second benchmark, designed not to measure anyevent overhead,<br/> ML&gt; but to measure real-world performance of a socket server.<br/> &gt;&gt; <br/> &gt;&gt; and that /sessions code also shows use of the asyncio module. if you can<br/> &gt;&gt; benchmark that i would be interested in the results. <br/><br/> ML&gt; Hmm, tt seems to have become fashionable lately to call synchronous I/O<br/> ML&gt; asynchronous (see IO::Async, another 100% synchronous framework). What<br/> ML&gt; exactly is asynchronous about the I/O in that example, it seems to be<br/> ML&gt; fully synchronous to me (just event-driven).<br/><br/>event loops are async in that you get callbacks as they are needed. sure<br/>you can&#39;t get true async behavior from any cpu/os combo but calling it<br/>async is no different than calling it parallel processing when it is<br/>just context switching among processes on a single cpu. the illusion and<br/>api are what matters. a better term may be non-blocking i/o (and socket<br/>connections) but that needs more explanation in some ways. my view is<br/>that threads are the real sync app style and event loops are the async<br/>style. but this is not the time nor place to discuss that.<br/><br/> &gt;&gt; i don&#39;t find that surprising. perl&#39;s i/o is decent and as i said above,<br/> &gt;&gt; a loaded server is doing mostly i/o. <br/><br/> ML&gt; Well, since the server in this benchmark hardly does anything, and as you<br/> ML&gt; can see by the results, the event loop completely dominates, and bad event<br/> ML&gt; loops are a thousand times slower than good ones.<br/><br/>i haven&#39;t looked at the benchmark stuff yet. i was browsing the code<br/>earlier.<br/><br/> ML&gt; When put into requests/s, this means that with POE, you are limited<br/> ML&gt; to &lt;1000 requests/s, while with EV you can easily reach hundreds of<br/> ML&gt; thousands.<br/><br/> ML&gt; Also, this does not explain at all why Event is so slow, and why Glib scales<br/> ML&gt; so extremely badly. Most of the stuff that slows down the perl-based event<br/> ML&gt; loop is clearly stuff that is much much faster in C.<br/><br/>poor memory management in the c code? i have done pure c event loops in<br/>a framework where memory management was fairly fast due to cached queues<br/>of known block sizes. alloc/free were usually a trivial call and the<br/>event code had it own private fixed size buffer queues. it had no<br/>problem doing 2k parallel web fetches including all the url parsing all<br/>on a single sparc. we had to throttle it down to keep up with the slower<br/>indexer. <br/><br/> ML&gt; For a reasonable event loop implemented in C, the overhead of<br/> ML&gt; calling select should completely dominate the rest of the<br/> ML&gt; processing (it does so in EV).<br/><br/>true, but bad c (and perl) code is all around us.<br/><br/> &gt;&gt; i will take a gander and see if i can play with it and add stem&#39;s loop<br/> &gt;&gt; to it. if you want to work on this with me, i wouldn&#39;t mind the help.<br/><br/> ML&gt; Well, can&#39;t say thereis much demand for it, but if you cna give me a pointer<br/> ML&gt; on these things in the docs I can probably come up with one before the next<br/> ML&gt; release:<br/><br/> ML&gt; - how can I do one iteration of the event loop? This is important<br/><br/>i don&#39;t have an api for oneevent. i still haven&#39;t seen a need for<br/>it. hence having stem wrap anyevent may be the better way. the goal for<br/>me is to have stem support more (and faster) event loops. if you are<br/>doing a stem app, you should use the stem event api.<br/><br/> ML&gt; for condvars: the function must not block after one or more events<br/> ML&gt; have been handled.<br/><br/>??<br/><br/> ML&gt; - how do I register a callback to be called when an fh or fd becomes<br/> ML&gt; &quot;readable&quot; or &quot;writable&quot;?<br/><br/>the sessions examples show plenty of that. very similar to event.pm overall.<br/><br/> ML&gt; - how can I register a relative timer?<br/><br/>relative? is that a delay timer (relative to now)? event.pm has hard<br/>(timing from before callback to next trigger) and soft (time from after<br/>callback to next trigger) timers.<br/><br/> ML&gt; - are there any limitations, for example, what happens when I register<br/> ML&gt; two read watchers for one fh (or fd)?<br/><br/>shouldn&#39;t be a problem if select handles it. the stem perl event loop is<br/>a wrapper around select.<br/><br/> ML&gt; - does stem provide something to catch signals synchronously?<br/><br/>either use event.pm as the core loop or the pure perl one can do it<br/>under 5.8 and safe signals.<br/><br/> ML&gt; - how about child status changes or exits?<br/><br/>signals are signals. it handles sigchld and the stem::proc module deals<br/>with reaping as needed.<br/><br/> ML&gt; The EV or Event implementation modules should give a good idea of whats<br/> ML&gt; required.<br/><br/> ML&gt; And for the documentation:<br/><br/> ML&gt; - how does stem handle time jumps, if at all?<br/><br/>??<br/><br/> ML&gt; - are it&#39;s timers based on absolute or wallclock time or relative/monotonic time?<br/><br/>iirc it checks wallclock (HiRes::time()) after each call to select and<br/>gets its current delta from that. you can&#39;t trust a relative clock as it<br/>will skew around.<br/><br/>uri<br/><br/>-- <br/>Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --<br/>----- Perl Code Review , Architecture, Development, Training, Support ------<br/>--------- Free Perl Training --- http://perlhunter.com/college.html ---------<br/>--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1110.html Sat, 26 Apr 2008 02:34:41 +0000 Benchmarking Stem :) by Marc Lehmann Ok, I have enough for a benchmark, just short of being able to provide a<br/>working implementation.<br/><br/>I actually ran out of memory with the Stem implementation, it seems to use<br/>a lot of additional memory when running the event loop. I had to reduce<br/>the number of handles to 20000.<br/><br/>Otherwise, it looks quite good (this is the synthetic benchmark that<br/>doesn&#39;t test event loop performance, just overheads):<br/><br/> name watchers bytes create invoke <br/> EV/EV 100000 244 0.54 0.45 <br/> Perl/Any 100000 513 4.61 0.87 <br/> Stem/Any 20000 1159 31.51 9.12 <br/> Event/Any 16000 936 38.80 31.91 <br/> POE/Any 2000 6658 108.61 726.39 <br/><br/>It is only 10 times slower than anyevents pure perl backend, but three<br/>times faster than Event.<br/><br/>For the large server benchmark, it still looks very good:<br/><br/> name sockets create request <br/> EV 20000 68.51 10.65 <br/> Perl 20000 73.58 112.90 <br/> Event 20000 199.29 252.45 <br/> Stem 20000 128.11 660.92 <br/> Glib 20000 632.13 1818.40 <br/> POE 20000 344.56 12154.89 <br/><br/>Only 6 times slower than anyevents pure perl backend, but faster than Glib<br/>(ok, glib clearly has issues :)<br/><br/>So it is actually quite good, and quite usable, except for the out of<br/>memory issue.<br/><br/>(This is without the multiple watchers per fd/combo workaround, btw.,<br/>which would only affect create speed).<br/><br/>It hurts a bit to come so far and then to only fail because stem has no<br/>one_iteration-like functionality, though (I would go with busy waiting, if<br/>that were implementable, but thats not reasonable to implement either).<br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1109.html Sat, 26 Apr 2008 00:15:11 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Sat, Apr 26, 2008 at 01:14:07AM -0400, Uri Guttman &lt;uri@stemsystems.com&gt; wrote:<br/>&gt; actually it makes more sense to me to wrap anyevent in stem. it already<br/><br/>Yes, after it turned out that stopping the loop also seems to clear events<br/>it became clear that Stem cannot provide even the stripped down interface<br/>of anyevent (even when one works aorund the bugs that make it unusable).<br/><br/>Too bad, I&#39;d liked to benchmark it, but thats almost out of the question<br/>(maybe with a quick hack...).<br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1108.html Sat, 26 Apr 2008 00:00:39 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann Hmm, more bugs:<br/><br/> sub stopbusywaiting {<br/> Stem::Event::stop_loop;<br/> }<br/><br/> my $stopper = new Stem::Event::Timer<br/> object =&gt; $dummy,<br/> method =&gt; &quot;stopbusywaiting&quot;,<br/> delay =&gt; 0.05,<br/> interval =&gt; 0.05; # bug workaround<br/><br/> warn &quot;a\n&quot;;<br/> $stopper-&gt;start;<br/> Stem::Event::start_loop;<br/> $stopper-&gt;cancel;<br/> warn &quot;b\n&quot;;<br/><br/>This always takes a second, here is an strace:<br/><br/> http://ue.tst.eu/57e55320bf26d8c4ae403e722bd7e268.txt<br/><br/>adding &quot;use Time::HiRes &#39;time&#39;&quot; to Perl.pm makes it run fast (yes,<br/>diretcly below the code that should handle this, something is broken<br/>witht he time::hires loading code apparently, maybe its this weird<br/>core-overwriting issue).<br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1107.html Fri, 25 Apr 2008 23:53:49 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Sat, Apr 26, 2008 at 01:14:07AM -0400, Uri Guttman &lt;uri@stemsystems.com&gt; wrote:<br/>&gt; &gt;&gt;&gt;&gt;&gt; &quot;ML&quot; == Marc Lehmann &lt;schmorp@schmorp.de&gt; writes:<br/>&gt; <br/>&gt; ML&gt; On Fri, Apr 25, 2008 at 11:40:03PM -0400, Uri Guttman &lt;uri@stemsystems.com&gt; wrote:<br/>&gt; &gt;&gt; check out stem&#39;s pure perl event loop. there are examples in the<br/>&gt; <br/>&gt; ML&gt; Maybe I&#39;ll provide a backend for stem.<br/>&gt; <br/>&gt; actually it makes more sense to me to wrap anyevent in stem. it already<br/>&gt; has several event wrappers (pure perl, event.pm and tk) and wrapping is<br/>&gt; very easy to do. not much different than the code i see in anyevent.<br/><br/>FYI: I think I found a bug, one-shot timer events never get reported:<br/><br/>Pelr.pm:<br/>- calls timer_triggered,<br/>- which cancels,<br/>- which sets active to 0,<br/>- then calls trigger<br/>- which returns becasue active is 0<br/><br/>and callback never gets invoked.<br/><br/>Maybe my reading of the sourcecode is wrong, but I can&#39;t for the life of it<br/>get any timer event out of stem.<br/><br/>-- <br/> The choice of a Deliantra, the free code+content MORPG<br/> -----==- _GNU_ http://www.deliantra.net<br/> ----==-- _ generation<br/> ---==---(_)__ __ ____ __ Marc Lehmann<br/> --==---/ / _ \/ // /\ \/ / pcg@goof.com<br/> -=====/_/_//_/\_,_/ /_/\_\<br/> http://www.nntp.perl.org/group/perl.loop/2008/04/msg1106.html Fri, 25 Apr 2008 23:43:57 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Sat, Apr 26, 2008 at 01:14:07AM -0400, Uri Guttman &lt;uri@stemsystems.com&gt; wrote:<br/>&gt; ML&gt; Maybe I&#39;ll provide a backend for stem.<br/>&gt; <br/>&gt; actually it makes more sense to me to wrap anyevent in stem. it already<br/><br/>of course, using anyevent always makes sense.<br/><br/>however, using anyevent doesn&#39;t solve the interoeprability problem: you<br/>still cannot use modules using anyevent when you don&#39;t use the anyevent<br/>but the wx interface, for example.<br/><br/>&gt; has several event wrappers (pure perl, event.pm and tk) and wrapping is<br/>&gt; very easy to do. not much different than the code i see in anyevent.<br/><br/>Yes, but that doesn&#39;t give you much advantage - as long as your module<br/>isn&#39;t good citizen and plays nicely with other modules by monopolising the<br/>process it is not interoperable.<br/><br/>Making anyevent compatible to stem enables anyevent modules to be used in<br/>stem. making stem use anyevent doesn&#39;t achieve that aslong as it doesn&#39;t<br/>use it&#39;s anyevent backend, and it cnanot be used in other programs as<br/>well, as it isn&#39;t event-loop agnostic because it forces the user to use<br/>&quot;stem&quot; as the event loop.<br/><br/>Also, this would make it impossible to benchmark the pure perl event loop<br/>- I would *prepdict* (but i am bad at that) that it will be the slowest<br/>one, ignoring POE, which I expect to be much slower still.<br/><br/>&gt; ML&gt; Especially in the important case of many handles/few active ones, an approach<br/>&gt; ML&gt; of &quot;scan all handles&quot; is very slow.<br/>&gt; <br/>&gt; my code doesn&#39;t scan all handle, but scan all writeable events to see if<br/>&gt; their handle bits are set.<br/><br/>That&#39;s even worse, as there can be many more events (watchers?) then file<br/>descriptors (in the first benchmark you would scan, say, 10000 event<br/>watchers for the same fd). even if not, it&#39;s slow O(n), compared to fast<br/>O(n) that you can achieve with scanning the bitmasks.<br/><br/>It is only fast if you have a lot of handles and very few active watchers,<br/>which isn&#39;t too typical (who uses all those extra fd&#39;s if not your<br/>program?).<br/><br/>In any case, the &quot;scan mask&quot; approach is about many times faster in the<br/>actual benchmark with 10000 handles and 100 active ones, simply because<br/>scanning a mask is so much faster.<br/><br/>Besides, select returns the number of active handles, so one could use<br/>both approachs and select between them, e.g. when more than 80% of the<br/>handles are active, use the scan-all-handles method, otherwise the bitmask<br/>method.<br/><br/>&gt; descriptors increment and can cause bloat of the array if you have many<br/>&gt; in use (and not all of them in the event loop).<br/><br/>That is not a common case, besides, arrays are very compact, unlike<br/>hashes, so it&#39;s not a clear win (note how the pure perl backend in<br/>anyevent comes out as one of the backends using the leats amount of<br/>memory).<br/><br/>In any case, a lot of technology in the kernel goes into providing &quot;small<br/>integers&quot; as fd&#39;s, not taking advantage of that gives away optimisaiton<br/>opportunities. In this case, unix guarantees that the memory use is<br/>bounded (there is even a resource limit for it, and reserving 4 or 8<br/>bytes/file descriptor is nothing really).<br/><br/>Trying to avoid bloat on that side is the wrogn side to optimise for.<br/><br/>&gt; event loops are async in that you get callbacks as they are needed. sure<br/><br/>Yes, but the I/O isn&#39;t async, which was my point. asynchronous I/O is<br/>quite a different beast, but few people really use it. (which is a pity,<br/>but only pelr ahs a IMnsHO decent module for it).<br/><br/>&gt; api are what matters. a better term may be non-blocking i/o (and socket<br/><br/>It&#39;s actually the only correct term, as no I/O is done in the event loop.<br/><br/>&gt; ML&gt; Also, this does not explain at all why Event is so slow, and why Glib scales<br/>&gt; ML&gt; so extremely badly. Most of the stuff that slows down the perl-based event<br/>&gt; ML&gt; loop is clearly stuff that is much much faster in C.<br/>&gt; <br/>&gt; poor memory management in the c code?<br/><br/>Perl&#39;s memory management is quite good, yeah. I do suspect that it<br/>has somethign to do with glib scanning its watcher list (ALL of them)<br/>rep