perl.loop http://www.nntp.perl.org/group/perl.loop/ ... Copyright 1998-2013 perl.org Sat, 25 May 2013 04:42:32 +0000 ask@perl.org Re: events and shared memory by Joshua N Pritikin On Wed, Oct 10, 2012 at 01:40:22AM -0700, Max V. Bouglacoff wrote:<br/>&gt; I&#39;m trying to use Event module along with IPC::Shareable. The problem is<br/>&gt; that Event does not react on changes of scalar vars placed in shared memory.<br/>&gt; The code looks like this:<br/>&gt; <br/>&gt; ...<br/>&gt; <br/>&gt; tie $VAR,&nbsp; &#39;IPC::Shareable&#39;,&nbsp; &#39;SCAL&#39;;<br/>&gt; ...<br/>&gt; Event-&gt;var(<br/>&gt; &nbsp;&nbsp;&nbsp; var =&gt; \$VAR,<br/>&gt; &nbsp;&nbsp;&nbsp; poll =&gt; &#39;w&#39;,<br/>&gt; &nbsp;&nbsp;&nbsp; cb =&gt; sub {<br/>&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # some code<br/>&gt; <br/>&gt; &nbsp;&nbsp;&nbsp; }<br/>&gt; &nbsp; );<br/>&gt; ...<br/>&gt; To clarify: when first process modifies $VAR the<br/>&gt; changes are visible in second process immediately, but<br/>&gt; there is no reaction on Event facility (in second process).<br/>&gt; <br/>&gt; Would you be so kind to help me with this?<br/><br/>Event&#39;s var watcher depends on perl triggering the watcher when <br/>modifying the variable. This will not happen when the variable is <br/>modified by another process.<br/><br/>Rather than using shared memory, I recommend you create a socket pair <br/>(like a pipe) between the two processes. Then you can write a byte on <br/>one side and use the Event io watcher to notice in the receiving <br/>process. Will this work for your use case?<br/><br/>&gt; =========<br/>&gt; This is perl, v5.8.8 built for i486-linux-thread-multi<br/>&gt; Event-1.20<br/>&gt; IPC-Shareable-0.60<br/>&gt; <br/>&gt; Linux breslau 2.6.36 #2 SMP PREEMPT Thu Jan 13 10:56:43 EET 2011 i686 AMD Athlon(tm) 64 X2 Dual Core Processor 5200+ AuthenticAMD GNU/Linux<br/>&gt; Slackware 12.1.0<br/><br/>-- <br/>Joshua N. Pritikin<br/>Department of Psychology<br/>University of Virginia<br/>Gilmer Hall 102; Charlottesville, VA 22903<br/>http://people.virginia.edu/~jnp3bc<br/> http://www.nntp.perl.org/group/perl.loop/2012/10/msg1128.html Wed, 10 Oct 2012 05:34:28 +0000 Re: Event.pm error message by Joshua N Pritikin On Mon, Dec 29, 2008 at 01:41:53PM -0500, Jeff Boes wrote:<br/>&gt; Joshua N Pritikin wrote:<br/>&gt; &gt; Let us know what happens!<br/>&gt; <br/>&gt; I am a bit confused, still. Should I make *all* my events reentrant,<br/><br/>The reentrant constraint is just for debugging. You don&#39;t want to keep <br/>re-entering the main event loop infinitely because you&#39;ll eventually run <br/>out of stack. If you are certain that your code works correctly then you <br/>can make all your watchers reentrant to avoid triggering the error.<br/><br/>&gt; Or just the ones I expect to be fired up *from* the &quot;sweep&quot; calls?<br/><br/>Yah, that&#39;s the disciplined way to do it.<br/> http://www.nntp.perl.org/group/perl.loop/2008/12/msg1127.html Mon, 29 Dec 2008 11:25:56 +0000 Re: Event.pm error message by Joshua N Pritikin On Mon, Dec 29, 2008 at 09:51:16AM -0500, Jeff Boes wrote:<br/>&gt; Hello! I posted this to the mailing list some time ago but never got a <br/>&gt; response.<br/><br/>I didn&#39;t see your post. Are you sure it got through?<br/><br/>&gt; Do you have any insights?<br/>&gt; <br/>&gt; I&#39;m upgrading an ancient (2004-era) server to the modern era:<br/>&gt; <br/>&gt; 2.6.18-92.1.6.el5 x86_64 x86_64 x86_64 GNU/Linux Perl 5.10 Event.pm 1.11<br/>&gt; <br/>&gt; One of my applications throws the following error once it&#39;s been running for a<br/>&gt; few minutes as a daemon:<br/>&gt; <br/>&gt; Assertion (((pe_watcher*)wa)-&gt;flags &amp; 0x0008) || !wa-&gt;running failed: file<br/>&gt; &quot;c/queue.c&quot;<br/><br/>That looks like c/queue.c line 43. Try making your watcher reentrant <br/>with $wa-&gt;reentrant(1) before you enter your main loop. After doing <br/>that, does it work?<br/> http://www.nntp.perl.org/group/perl.loop/2008/12/msg1126.html Mon, 29 Dec 2008 10:03:48 +0000 Event.dylib issue by Thomas Keller Greetings,<br/>I&#39;m new to integrating C with Perl as well as the Event module.<br/>Trying the example:<br/>--------------<br/>use strict;<br/>use Inline with =&gt; &#39;Event&#39;;<br/>use Inline C =&gt; &lt;&lt;&#39;EOC&#39;;<br/>void c_callback(pe_event * event)<br/>{<br/>printf(&quot;Here is the C callback!\n&quot;);<br/>}<br/>EOC<br/>Event-&gt;timer( desc =&gt; &#39;Perl timer with C callback.&#39;,<br/> interval =&gt; 2,<br/> cb =&gt; \&amp;c_callback,<br/> );<br/>Event::loop;<br/>----------------<br/>I get the following error:<br/>$ perl event_timer.pl<br/>make: *** No rule to make target `/opt/local/lib/perl5/site_perl/ <br/>5.10.0/darwin-2level/auto/Event/Event.dylib&#39;, needed by `subdirs&#39;. <br/>Stop.<br/><br/>A problem was encountered while attempting to compile and install your <br/>Inline<br/>C code. The command that failed was:<br/> make &gt; out.make 2&gt;&amp;1<br/>------------------<br/><br/>There does not seem to be an Event.dylib at the expected location:<br/>$ ls -l /opt/local/lib/perl5/site_perl/5.10.0/darwin-2level/auto/Event/<br/>total 184<br/>-r--r--r-- 1 root admin 0 Nov 20 08:43 Event.bs<br/>-r-xr-xr-x 1 root admin 92992 Nov 20 08:43 Event.bundle<br/><br/><br/>Your help would be greatly appreciated.<br/>regards,<br/>Tom Keller<br/><br/><br/>Thomas J Keller, PhD<br/>MMI Shared Resource Facility<br/>Oregon Health &amp; Science University<br/>Portland, OR 97239<br/><br/>503-494-2442<br/>kellert@ohsu.edu<br/><br/><br/><br/> http://www.nntp.perl.org/group/perl.loop/2008/11/msg1125.html Thu, 20 Nov 2008 13:10:12 +0000 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/>repeatedly, and when removing, who knows, it might run a singly-linked<br/>list to its end to remove the watcher.<br/><br/>As for Event, I think it simply does way too much around simple callback<br/>invocation, for example it uses its event queue and adds events at the end<br/>(walking the list each time). All that the event queue has done for me,<br/>hwoever, was causing infite memory growth when it added multiple events<br/>for the same fd again and again becasue some high-priority watcher got<br/>precedence.<br/><br/>(I have nothing against event queues, you need one, but one *can* manage<br/>it abysmally).<br/><br/>&gt; a framework where memory management was fairly fast due to cached queues<br/>&gt; of known block sizes. alloc/free were usually a trivial call and the<br/>&gt; event code had it own private fixed size buffer queues. it had no<br/>&gt; problem doing 2k parallel web fetches including all the url parsing all<br/>&gt; on a single sparc. we had to throttle it down to keep up with the slower<br/><br/>hehe :)<br/><br/>&gt; ML&gt; For a reasonable event loop implemented in C, the overhead of<br/>&gt; ML&gt; calling select should completely dominate the rest of the<br/>&gt; ML&gt; processing (it does so in EV).<br/>&gt; <br/>&gt; true, but bad c (and perl) code is all around us.<br/><br/>hehe :/<br/><br/>&gt; ML&gt; - how can I do one iteration of the event loop? This is important<br/>&gt; <br/>&gt; i don&#39;t have an api for oneevent. i still haven&#39;t seen a need for<br/>&gt; it.<br/><br/>&gt; hence having stem wrap anyevent may be the better way.<br/><br/>Its the easier way, because you don&#39;t have to provide the common interface<br/>anyevent offers, but it is also far less useful - since Stem seems to be<br/>like POE in that it dominates the process (it&#39;s me and nothing else),<br/>there is liekly little pratical need to interoperability, but it sure<br/>would be nice :)<br/><br/>&gt; the goal for me is to have stem support more (and faster) event loops.<br/>&gt; if you are doing a stem app, you should use the stem event api.<br/><br/>*sigh*, I think the world would be a much better place if not every module<br/>author emplyong events insisted on ruling out all others :)<br/><br/>&gt; ML&gt; for condvars: the function must not block after one or more events<br/>&gt; ML&gt; have been handled.<br/>&gt; <br/>&gt; ??<br/><br/>Some event models had bugs in that they:<br/><br/>1. handled some timer events<br/>2. blocked waiting for some i/o events<br/><br/>This must not happen in the &quot;one event loop iteration&quot; function. It can<br/>handle as many events as it likes, but when it handles at least one event,<br/>it must not block.<br/><br/>&gt; ML&gt; - how do I register a callback to be called when an fh or fd becomes<br/>&gt; ML&gt; &quot;readable&quot; or &quot;writable&quot;?<br/>&gt; <br/>&gt; the sessions examples show plenty of that. very similar to event.pm overall.<br/><br/>Actually, I tried, but I found the testsuite is much clearer on that.<br/><br/>&gt; ML&gt; - how can I register a relative timer?<br/>&gt; <br/>&gt; relative? is that a delay timer (relative to now)? event.pm has hard<br/>&gt; (timing from before callback to next trigger) and soft (time from after<br/>&gt; callback to next trigger) timers.<br/><br/>I found it, it only supports relative timers (but internally uses absolute<br/>timing).<br/><br/>&gt; ML&gt; - are there any limitations, for example, what happens when I register<br/>&gt; ML&gt; two read watchers for one fh (or fd)?<br/>&gt; <br/>&gt; shouldn&#39;t be a problem if select handles it. the stem perl event loop is<br/>&gt; a wrapper around select.<br/><br/>Well, the Tk backend doesn&#39;t handle it, unless I missed something, and the<br/>lowest common denominator counts.<br/><br/>(Since AnyEvent prefers using its Tk backend this is not an issue unles sa<br/>user would force the Stem backend).<br/><br/>&gt; ML&gt; - how about child status changes or exits?<br/>&gt; <br/>&gt; signals are signals. it handles sigchld and the stem::proc module deals<br/>&gt; with reaping as needed.<br/><br/>Well, signals are signals, but we are talking about waitpid here - how do<br/>I get the info that stem::proc reaps in my sigchld handler?<br/><br/>&gt; ML&gt; - how does stem handle time jumps, if at all?<br/>&gt; <br/>&gt; ??<br/><br/>bios sets the time to 2010, ntp resets it to 2005, do stem programs then<br/>sleep for 5 years? answer is: likely ses.<br/><br/>&gt; ML&gt; - are it&#39;s timers based on absolute or wallclock time or relative/monotonic time?<br/>&gt; <br/>&gt; iirc it checks wallclock (HiRes::time()) after each call to select and<br/>&gt; gets its current delta from that. you can&#39;t trust a relative clock as it<br/>&gt; will skew around.<br/><br/>It is the othere way around, a relative clock does exactly the same thing<br/>as your timers (you tell it to delay 5 seconds, it will delay 5 seconds),<br/>an absoltue clock does not, for example, a user who registers a 5 second<br/>delay with Stem might find out that it takes years to complete because it<br/>uses wallclock time which can change, unlike for example,a true monotonic<br/>clock, or some other time source that allows me to build relative timing.<br/><br/>But that is ok, as far as I know:<br/><br/>- libevent and Event::Lib use a monotonic clock ti gte relative timers<br/>- Event has some crude checking for time jumps<br/>- EV handles relative and absolute timers about perfectly<br/>- all else just suffers from timejumps<br/><br/>So stem is in good company, its&#39; a perfectionist issue (although each one<br/>of my programs that didn&#39;t handle relative timers correctly got a bug<br/>report in the past because of that, so it happens quite often, even on<br/>servers).<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/msg1105.html Fri, 25 Apr 2008 23:31:03 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Sat, Apr 26, 2008 at 07:01:39AM +0200, Marc Lehmann &lt;schmorp@schmorp.de&gt; wrote:<br/>&gt; And another one:<br/><br/>does Stem deal with subsecond delay values? Under what circumstances?<br/>AnyEvent guarantees subsecond accuracy currently.<br/><br/>Also:<br/><br/> The &rsquo;hard&rsquo; attribute means that the next interval delay starts<br/> before the callback to the object is made. If a soft timer is selected<br/> (hard is 0), the delay starts after the callback returns. So the hard<br/> timer ignores the time taken by the callback and so it is a more<br/> accurate timer. The accuracy a soft timer is affected by how much time<br/> the callback takes.<br/><br/>It is nice to have a hard timer, but please implement clumping. Not<br/>implementing clumping makes this type of timer completely unusable in<br/>practise, as a time jump or stopping the program for a long time has makes<br/>it potentially unusable.<br/><br/>(In fact, this inability to use Event&#39;s hard timers was one of the reasons<br/>I was looking for a different event loop. EV doesn&#39;t do clumping, however,<br/>as it has two timer types that solve time-jump and stopping-related<br/>problems diferently).<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/msg1104.html Fri, 25 Apr 2008 22:05:08 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Sat, Apr 26, 2008 at 06:48:55AM +0200, Marc Lehmann &lt;schmorp@schmorp.de&gt; wrote:<br/>&gt; Well, can&#39;t say thereis much demand for it, but if you cna give me a pointer<br/>&gt; on these things in the docs I can probably come up with one before the next<br/>&gt; release:<br/><br/>Looking at Stem::Event, which hopefully is the right place to look, I cna<br/>come up with soem answres and some more refined questions :)<br/><br/>Here is a new question:<br/><br/>- How do I select a specific event loop backend to be used?<br/><br/>&gt; - does stem provide something to catch signals synchronously?<br/><br/>doesn&#39;t seem to be documented, I assume so.<br/><br/>&gt; - how can I do one iteration of the event loop? This is important<br/><br/>Interestingly, the manpage for &quot;Stem::Event # event loop&quot; doesn&#39;t mention any<br/>way to start said event loop.<br/><br/>The source code has init_loop, start_loop and, interestingly, stop_loop.<br/><br/>Does that mena I have to initialsie the event loop myself? Is initialising<br/>it multiple times a problem (obviously, code using anyevent can&#39;t be<br/>bothered to implement workarounds for stem, so if that were a problem,<br/>stem couldn&#39;t be used by default. Thats not too bad, however, as it would<br/>sitll be used if the main program uses stem).<br/><br/>&gt; - how do I register a callback to be called when an fh or fd becomes<br/>&gt; &quot;readable&quot; or &quot;writable&quot;?<br/><br/>This is also not documented. All it says is: <br/><br/> This class creates an event that will trigger a callback whenever its<br/> file descriptor has data to be read. [...]<br/> <br/>It doesn&#39;t say how to pass &quot;its dile descriptor&quot;, or wether it also works<br/>with file handles.<br/><br/>&gt; - how can I register a relative timer?<br/><br/>Solved :) Whats missing is how I cancel that time, does it automatically<br/>cancel itself when the returned object gets forgotten by the calling code?<br/><br/>&gt; - are there any limitations, for example, what happens when I register<br/>&gt; two read watchers for one fh (or fd)?<br/><br/>The answre seems to be: stem needs the same workaround as Tk, unless I<br/>overlooked some internal layer.<br/><br/>&gt; - how about child status changes or exits?<br/><br/>Doesn&#39;t seem to be supported, so AnyEvent will fall back to its own code<br/>(there is nothing wrong with that, POE is much worse, as its code is<br/>broken but insists on reaping children so one cnanot even use one&#39;s own<br/>implementation).<br/><br/>&gt; - how does stem handle time jumps, if at all?<br/><br/>Can&#39;t really find anything here either, I guess changing the clock<br/>requires a restart.<br/><br/>&gt; - are it&#39;s timers based on absolute or wallclock time or relative/monotonic time?<br/><br/>Seems to be absolute time.<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/msg1103.html Fri, 25 Apr 2008 22:01:47 +0000 Re: benchmarking various event loops with and without anyevent by Marc Lehmann On Fri, Apr 25, 2008 at 11:40:03PM -0400, Uri Guttman &lt;uri@stemsystems.com&gt; wrote:<br/>&gt; check out stem&#39;s pure perl event loop. there are examples in the<br/><br/>Maybe I&#39;ll provide a backend for stem.<br/><br/>&gt; modules. it does things in a different direction and doesn&#39;t scan<br/>&gt; select&#39;s bit masks but instead it scans the interesting handles and see<br/>&gt; whether their bits are set. it should exhibit good behavior under growth<br/>&gt; as all the data are managed in hashes.<br/><br/>That is exactly as the anyevent perl backend did in the previous<br/>version. I don&#39;t see how that should exhibit good behaviour - file<br/>descristpors are small integers, so hashes only add overhead over arrays,<br/>and checking every file descriptor that way is much slower than scanning<br/>the bitmask.<br/><br/>Especially in the important case of many handles/few active ones, an approach<br/>of &quot;scan all handles&quot; is very slow.<br/><br/>(The benchmarks reflect this, you could try with an older anyevent<br/>release where we just check the keys of the hash storing fd information:<br/>performance is much lower).<br/><br/>&gt; ML&gt; I then made a second benchmark, designed not to measure anyevent overhead,<br/>&gt; ML&gt; but to measure real-world performance of a socket server.<br/>&gt; <br/>&gt; and that /sessions code also shows use of the asyncio module. if you can<br/>&gt; benchmark that i would be interested in the results. <br/><br/>Hmm, tt seems to have become fashionable lately to call synchronous I/O<br/>asynchronous (see IO::Async, another 100% synchronous framework). What<br/>exactly is asynchronous about the I/O in that example, it seems to be<br/>fully synchronous to me (just event-driven).<br/><br/>&gt; ML&gt; For small servers, the overhead introduced by running a lot of perl<br/>&gt; ML&gt; opcodes per iteration dominates, however, reflected in the last benchmark.<br/>&gt; <br/>&gt; in a heavily loaded server most of the work in in the i/o and should<br/>&gt; overwhelm the event loop itself. that is the whole purpose of event<br/>&gt; loops as we all know here. <br/><br/>I actually don&#39;t know that. When I write response data (such as a file in<br/>my anime server), the performance of the event loop completely dominates<br/>(ignoring IO::AIO overhead in this case, which also of coruse relies on<br/>the event loop).<br/><br/>Of course, select/poll don&#39;t scale at all, unless the majority of handles<br/>is active, also not very typical of heavily loaded servers.<br/><br/>&gt; ML&gt; However, the net result is that the pure perl event loop performs<br/>&gt; ML&gt; better than almost all other event loops (EV being the only exception)<br/>&gt; ML&gt; ins erious/medium-sized cases, while I originally expected it to fail<br/>&gt; ML&gt; completely w.r.t. performance and being only usable as a workaround when<br/>&gt; ML&gt; no &quot;better&quot; event module is installed.<br/>&gt; <br/>&gt; i don&#39;t find that surprising. perl&#39;s i/o is decent and as i said above,<br/>&gt; a loaded server is doing mostly i/o. <br/><br/>Well, since the server in this benchmark hardly does anything, and as you<br/>can see by the results, the event loop completely dominates, and bad event<br/>loops are a thousand times slower than good ones.<br/><br/>When put into requests/s, this means that with POE, you are limited<br/>to &lt;1000 requests/s, while with EV you can easily reach hundreds of<br/>thousands.<br/><br/>Also, this does not explain at all why Event is so slow, and why Glib scales<br/>so extremely badly. Most of the stuff that slows down the perl-based event<br/>loop is clearly stuff that is much much faster in C.<br/><br/>For a reasonable event loop implemented in C, the overhead of calling<br/>select should completely dominate the rest of the processing (it does so in<br/>EV).<br/><br/>This is not the case for any of the event loops I tested with the<br/>exception of EV and Event (which &quot;only&quot; has high overhead, but it doesn&#39;t<br/>grow beyond reason).<br/><br/>&gt; i will take a gander and see if i can play with it and add stem&#39;s loop<br/>&gt; to it. if you want to work on this with me, i wouldn&#39;t mind the help.<br/><br/>Well, can&#39;t say thereis much demand for it, but if you cna give me a pointer<br/>on these things in the docs I can probably come up with one before the next<br/>release:<br/><br/>- how can I do one iteration of the event loop? This is important<br/> for condvars: the function must not block after one or more events<br/> have been handled.<br/>- how do I register a callback to be called when an fh or fd becomes<br/> &quot;readable&quot; or &quot;writable&quot;?<br/>- how can I register a relative timer?<br/>- are there any limitations, for example, what happens when I register<br/> two read watchers for one fh (or fd)?<br/>- does stem provide something to catch signals synchronously?<br/>- how about child status changes or exits?<br/><br/>The EV or Event implementation modules should give a good idea of whats<br/>required.<br/><br/>And for the documentation:<br/><br/>- how does stem handle time jumps, if at all?<br/>- are it&#39;s timers based on absolute or wallclock time or relative/monotonic time?<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/msg1102.html Fri, 25 Apr 2008 21:49:06 +0000 benchmarking various event loops with and without anyevent by Marc Lehmann Hi!<br/><br/>The next release of AnyEvent contains support for a few more &quot;backends&quot;,<br/>notably POE, so AnyEvent is now by definition compatible to POE (before it<br/>was only compatible when using an even loop used by POE, such as Event or<br/>EV that could be shared).<br/><br/>To get a feeling about the overheads imposed by the extra layer of<br/>AnyEvent and especially of the performance of the POE backend (which is<br/>severely limited by a number of design problems in POE), I made some<br/>benchmarks.<br/><br/>I started with benchmarking watcher creation/destruction time and callback<br/>invocation time.<br/><br/>The results were mostly as expected, with EV leading and POE being<br/>abysmal.<br/><br/>The surprising one was the pure perl implementation, which was quite on<br/>par with C-based event loops such as Event or Glib. I did expect the pure<br/>perl implementatioon to be at least a factor of three slower than Event or<br/>Glib.<br/><br/>As the pure perl loop wasn&#39;t written with high performance in mind, this<br/>prompted me to optimise it for some important cases (mostly to get rid of<br/>the O(n&sup2;) degenerate cases and improving the select bitmask parsing for<br/>the sparse case).<br/><br/>I then made a second benchmark, designed not to measure anyevent overhead,<br/>but to measure real-world performance of a socket server.<br/><br/>The result is that the pure perl event loop used as fallback in AnyEvent<br/>single-handedly beats Glib by a large margin, and even event by a factor<br/>of two.<br/><br/>For small servers, the overhead introduced by running a lot of perl<br/>opcodes per iteration dominates, however, reflected in the last benchmark.<br/><br/>However, the net result is that the pure perl event loop performs<br/>better than almost all other event loops (EV being the only exception)<br/>ins erious/medium-sized cases, while I originally expected it to fail<br/>completely w.r.t. performance and being only usable as a workaround when<br/>no &quot;better&quot; event module is installed.<br/><br/>All the benchmark data and explanations can be found here:<br/><br/>http://pod.tst.eu/http://cvs.schmorp.de/AnyEvent/lib/AnyEvent.pm#BENCHMARKS<br/><br/>The code is not yet released and likely still buggy (the question is<br/>whether any bugs affect the benchmark results). It is only available via<br/>CVS: http://software.schmorp.de/pkg/AnyEvent<br/><br/>Of course, I am very pleased by the performance of perl 5.10 in particular<br/>and perl in general. This case also shows that one can beat C code in<br/>many important cases by using better algorithms (i.e. by writing it the<br/>&quot;perlish&quot; way).<br/><br/>It also means one can write medium-sized servers without relying on any<br/>XS modules for performance, and that AnyEvent adds no serious overhead to<br/>programs.<br/><br/>Feedback would be appreciated, otherwise: enjoy :)<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/msg1101.html Fri, 25 Apr 2008 19:46:30 +0000 EV module questions by Peter Maynard Using EV for a daemon re-write and have run into a little trouble.<br/><br/>Original daemon redirected STDERR to a variable $stderr and each time<br/>through the daemon&#39;s while loop, I simply checked if the variable had<br/>data and wrote it to syslog as an error if it did. Then I&#39;d clear the<br/>variable and carry on.<br/><br/>I&#39;m now trying to re-create this using EV and I&#39;m having problemss.<br/><br/>NOTE: I can&#39;t write the output to a file and watch the file. Due to<br/>operational restrictions, STDERR must go directly to syslog.<br/><br/>I&#39;ve managed to setup a periodic watcher to write the $stderr variable<br/>to syslog, but it won&#39;t clear. I also tried to setup a watcher directly<br/>on STDERR, but that didn&#39;t seem to work at all.<br/><br/>Any suggestions or help would be greatly appreciated.<br/><br/>PS. Thanks for EV and Net::SNMP::EV. I was fighting to do this with<br/>POE and EV has been a life saver!<br/><br/>Peter Maynard<br/><br/> http://www.nntp.perl.org/group/perl.loop/2008/02/msg1100.html Sat, 02 Feb 2008 01:51:21 +0000 overview over the EV module family by Marc Lehmann It&#39;s been a while since I announced EV, and in the meantime, not only<br/>has EV proven itself in a lot of apps, the module family around it grew<br/>considerably.<br/><br/>With version 2.0, EV gained support for multiple event loops and embed<br/>watchers (a bit scarcely documented), so one can now use e.g. kqueue for<br/>sockets only and poll for overall event polling.<br/><br/>A number of new modules are now available, separately from the main EV<br/>distro:<br/><br/>- EV::ADNS<br/><br/> This is an interface to libadns, an asynchronous dns resolver library,<br/> that replaces EV::DNS which was removed from EV. It is written in C<br/> and is a nice example on how to access EV from the C level, and how to<br/> effectively integrate foreign event loop users (such as libadns).<br/><br/>- Net::SNMP::EV<br/><br/> This is an adaptor that makes non-blocking Net::SNMP requests run as<br/> part of the EV event loop. It is written fully in Perl and has no public<br/> interface, just loading it makes Net::SNMP requests use EV. This is a nice<br/> example on how to integrate a foreign event loop user using perl only.<br/><br/>- EV::Glib<br/><br/> This integrates the default glib maincontext into EV. That means that<br/> watchers registered via Glib (e.g. in gtk+ programs) are handled together<br/> with EV watchers. This doesn&#39;t make glib any faster (it&#39;s easily the slowest<br/> event loop I have seen), but it allows you to integrate glib/gtk+ programs<br/> into EV-based programs.<br/><br/>- Glib::EV<br/><br/> This is the opposite of EV::Glib - it uses EV as the polling backend for<br/> Glib. This, too, doesn&#39;t make glib any more efficient (its usually a bit<br/> less efficient with epoll for example), but allows one to use EV and EV<br/> watchers in glib/gtk+ programs (i.e. the main loop that runs is the glib<br/> one, while with EV::Glib the main loop would be the EV one).<br/><br/> If one has a lot of IO watchers or timers, then using this module<br/> might result in a drastic performance increase over glib (the &quot;lot of&quot;<br/> comes from the fact that epoll cannot efficiently emulate poll, but<br/> in practise this can already pay off when watching two or more file<br/> descriptors).<br/><br/>- AnyEvent::Impl::EV and AnyEvent::Impl::CoroEV<br/><br/> AnyEvent has had EV support for quite some time, thought I&#39;d mention this.<br/><br/>- Coro::EV, Coro::Util<br/><br/> When Coro detects that EV is used, it will use Coro::EV to efficiently<br/> hook into the event loop for non-blocking socket access.<br/> <br/> Likewise, Coro::Util will take advantage of EV::ADNS if available, when<br/> resolving dns domains.<br/><br/>Most of these were written to satisfy my most immediate personal and<br/>company needs, which explains the weird coverage. Hope it is useful to<br/>somebody else, too.<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/2007/12/msg1099.html Sun, 30 Dec 2007 17:16:48 +0000 Re: announcing the new EV module, a modern redesign of Event by Marc Lehmann On Fri, Dec 14, 2007 at 12:22:00AM +0100, Jochen Stenzel &lt;perl@jochen-stenzel.de&gt; wrote:<br/>&gt; &gt; So far, it seems everything works right. While EV is young and certainly<br/>&gt; &gt; has some bugs, it is used in a lot of projects, and really can&#39;t be<br/>&gt; &gt; _totally_ broken.<br/>&gt; <br/>&gt; I never thought it was broken. If there was an impression as if I wanted<br/>&gt; to express something like that, or even &quot;totally broken&quot;, I&#39;m very<br/>&gt; sorry.<br/><br/>Nono, I didn&#39;t get that impression at all. &quot;totally broken&quot; were only my<br/>words :)<br/><br/>&gt; I was curious, I played a bit, I hoped to use EV in a project<br/>&gt; (and actually started to do so now), some things didn&#39;t seem to work<br/>&gt; perfectly and so I made some notes, and yes given that I was under heavy<br/>&gt; time pressure I agree it was unwise to quickly send first impressions in<br/>&gt; between spontaneously.<br/><br/>Good. Happens to me, too (the reporting-too-early). I was actually<br/>surprised to see the debugger take a reference btw....<br/><br/>Its better this way than knowing about a bug and being too shy to report<br/>it :)<br/><br/>&gt; There was no adrenaline involved here ;-) As I said before: I consider<br/><br/>Your mail was worded quite neutrally, if that helps :) I said that mostly<br/>for the benefit of other people following the discussion.<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/2007/12/msg1098.html Thu, 13 Dec 2007 22:56:45 +0000 Re: announcing the new EV module, a modern redesign of Event by Jochen Stenzel <br/>Hi Marc,<br/><br/>&gt; So far, it seems everything works right. While EV is young and certainly<br/>&gt; has some bugs, it is used in a lot of projects, and really can&#39;t be<br/>&gt; _totally_ broken.<br/><br/>I never thought it was broken. If there was an impression as if I wanted<br/>to express something like that, or even &quot;totally broken&quot;, I&#39;m very<br/>sorry. I was curious, I played a bit, I hoped to use EV in a project<br/>(and actually started to do so now), some things didn&#39;t seem to work<br/>perfectly and so I made some notes, and yes given that I was under heavy<br/>time pressure I agree it was unwise to quickly send first impressions in<br/>between spontaneously.<br/><br/>Time pressure continues and so it could take a while until I can return<br/>to the test scripts and your detailed answer (thanks for that), but I<br/>just want to make clear now that there was absolutely no intention to<br/>blame you or your work. *If* there are bugs they can probably be fixed.<br/>There was no adrenaline involved here ;-) As I said before: I consider<br/>it great news you wrote and maintain EV, and I think you are the right<br/>man for such a project, according to my impressions. Sorry for any other<br/>impression.<br/><br/>Greetings<br/><br/> Jochen<br/><br/><br/><br/> http://www.nntp.perl.org/group/perl.loop/2007/12/msg1097.html Thu, 13 Dec 2007 15:22:14 +0000 io/timer combo examples [Was: Re: Replacement of Event with EV] by Marc Lehmann &gt; As it is trivial to create a separate timeout (and much faster than with<br/>&gt; Event, too), there is no drawback to this design.<br/><br/>As it might not be too obvious, here is (in pseudocode) an example<br/>of an idle timeout, i.e. a timeout that triggers afetr some time of<br/>inactivity. It uses two watchers (which is not required but customary):<br/><br/> # 60 seconds idle timeout<br/> my $to = EV::timer_ns 0, 60, sub {<br/> close $fh; ... log error;<br/> };<br/><br/> $fh = ... new socket;<br/> $to-&gt;again;<br/> my $wr = EV::io $fh, EV::READ, sub {<br/> $to-&gt;again; # reset timer<br/> # do stuff<br/> };<br/> my $ww = EV::io $fh, EV::WRITE, sub {<br/> $to-&gt;again; # reset timer<br/> # do stuff<br/> };<br/><br/>The read and write watchers can easily be started and stopped<br/>independently of each other this way, and also independent of the timeout<br/>($to-&gt;stop ... $to-&gt;again is a valid sequence to temporarily disable a<br/>timeout, e.g. when the connection is not dpoing any work and can be kept<br/>open).<br/><br/>If you try to do this in event and re-use one watcher&#39;s timeout, you will<br/>need to stop/start it each time you get activity, which is rather costly<br/>(and costs a lot when one uses e.g. the epoll backend). Of course one can<br/>use a separate watcher with Event, too.<br/><br/>If an overall timeout is required (e.g. a single request must be done<br/>afetr 90 seconds, no matter what), the code becomes simpler (basiclaly its<br/>then using a simple timer and never resets it):<br/><br/> # 90 seconds idle timeout<br/> $fh = ... new socket;<br/><br/> my $to = EV::timer_ns 90, 0, sub {<br/> close $fh; ... log error;<br/> };<br/><br/> my $wr = EV::io $fh, EV::READ, sub {<br/> # do stuff<br/> };<br/> my $ww = EV::io $fh, EV::WRITE, sub {<br/> # do stuff<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/2007/12/msg1096.html Thu, 06 Dec 2007 15:28:23 +0000 Re: Replacement of Event with EV by Uri Guttman &gt;&gt;&gt;&gt;&gt; &quot;ML&quot; == Marc Lehmann &lt;schmorp@schmorp.de&gt; writes:<br/><br/> ML&gt; Its a design decision. Combining timers with io watchers is unnatural,<br/> ML&gt; because:<br/><br/> ML&gt; - you often don&#39;t need both, so shouldn&#39;t be forced to pay for them<br/> ML&gt; - you can&#39;t choose the type of timeout (event only has absolute timers<br/> ML&gt; anyways, though, which are unsuitable for many tasks such as idle timeouts<br/> ML&gt; for i/o, where you need relative timeouts).<br/> ML&gt; - you have to manage two timeouts or weirder stuff when you have<br/> ML&gt; two separate i/o watchers, or use a third watcher (paying even more).<br/> ML&gt; - it is often unclear on which events exactly the timeout gets reset<br/> ML&gt; (if at all), and even if not, there is no flexibility (how do you<br/> ML&gt; chose between an idle timeout and an overall timeout<br/> ML&gt; for completion with Event? you cannot).<br/><br/> ML&gt; As it is trivial to create a separate timeout (and much faster than with<br/> ML&gt; Event, too), there is no drawback to this design.<br/><br/>i do that in stem&#39;s event layer too. i/o watchers are created and an<br/>optional timer is added if desired (a separate event with a different<br/>method to callback into the object). this means all the event layer<br/>needs is simple i/o watchers and a simple timer. my code builds up the<br/>combined i/o with timer as needed. much cleaner and easier to manage at<br/>all levels.<br/><br/>as marc said it is also simpler in the lower levels to code up. and i<br/>bet most i/o watchers don&#39;t need timers which saves on the storage and<br/>coding.<br/><br/>uri<br/><br/>-- <br/>Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com<br/>--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-<br/>Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org<br/> http://www.nntp.perl.org/group/perl.loop/2007/12/msg1095.html Thu, 06 Dec 2007 07:04:49 +0000 Re: FAIL Event-1.09 i686-linux 2.4.20-8smp by Joshua N Pritikin On Thu, Dec 06, 2007 at 12:35:12PM +0200, Alexandr Ciornii wrote:<br/>&gt; Yes, I can build many other modules fine.<br/>&gt; You can see similar failures here:<br/>&gt; http://www.nntp.perl.org/group/perl.cpan.testers/2007/10/msg712278.html<br/>&gt; http://www.nntp.perl.org/group/perl.cpan.testers/2007/10/msg670107.html<br/><br/>Oh, that helps. All these failures occurred with perl 5.5.5. That&#39;s a <br/>really old version.<br/><br/>&gt; In general all testing errors are shown here:<br/>&gt; http://cpantesters.perl.org/show/Event.html#Event-1.09<br/><br/>Can you retry with a more recent version? Even perl 5.6 is really old by <br/>now. My development box has 5.8.8.<br/> http://www.nntp.perl.org/group/perl.loop/2007/12/msg1094.html Thu, 06 Dec 2007 06:14:57 +0000 Re: announcing the new EV module, a modern redesign of Event by Marc Lehmann On Thu, Dec 06, 2007 at 01:07:21AM +0100, Jochen Stenzel &lt;perl@jochen-stenzel.de&gt; wrote:<br/>&gt; * I *could* stop the loop in the debugger today, but it took a while:<br/><br/>Although the behaviour is consistent with any other extension module for<br/>perl, I tried to document this in the next EV release:<br/><br/> =head1 PERL SIGNALS<br/><br/> While Perl signal handling (C&lt;%SIG&gt;) is not affected by EV, the behaviour<br/> with EV is as with any other C library: signals will only be handled when<br/> Perl runs, which means your signal handler might be invoked only the next<br/> time an event gets handles.<br/><br/> The solution is to use the the EV signal handlers (see C&lt;EV::signal&gt;). If<br/> you cannot do this for whatever reason, you can also force a watcher to be<br/> called on every iteration by installing a C&lt;EV::check&gt; watcher:<br/><br/> my $async_check = EV::check sub { };<br/><br/> This ensures that perl shortly gets into control for a short time.<br/><br/>Note, however, that this does not work for the perl debugger as the perl<br/>debugger can only stop at the next perl statement to be executed - this is<br/>a limitation of perl (or more precisely the debugger).<br/><br/>As this is also the exact same behaviour as with Event (or other event<br/>loops), so I find it rather surprising that it needs mentioning, but<br/>I hope the additional documentation is not wasted and actually proves<br/>helpful to somebody.<br/><br/>(But then, signal handling does require knowledge of the underlying<br/>operating system handling of signals).<br/><br/>-- <br/> The choice of a<br/> -----==- _GNU_<br/> ----==-- _ generation Marc Lehmann<br/> ---==---(_)__ __ ____ __ pcg@goof.com<br/> --==---/ / _ \/ // /\ \/ / http://schmorp.de/<br/> -=====/_/_//_/\_,_/ /_/\_\ XX11-RIPE<br/> http://www.nntp.perl.org/group/perl.loop/2007/12/msg1093.html Wed, 05 Dec 2007 19:09:14 +0000 Re: announcing the new EV module, a modern redesign of Event by Marc Lehmann On Thu, Dec 06, 2007 at 01:07:21AM +0100, Jochen Stenzel &lt;perl@jochen-stenzel.de&gt; wrote:<br/>&gt; &gt; any signals, and in fatc, I cannot reproduce this. Are you sure that your<br/>&gt; &gt; tty settings actually do anything with CTRL-C (such as sending an INT)?<br/>&gt; <br/>&gt; I am - I retried it today, other programs receive the signal and the<br/>&gt; effect is the same if I send the signal via kill from another terminal.<br/><br/>Here is what happens on windows btw: at least activestate perl overrides<br/>the system console handler and thus disables those signals. As it doesn&#39;t<br/>provide signal emulation for other programs you cnanot catch those signals<br/>anymore, and there is nothing one can do about it. Or to put it in other<br/>words, perl actually emulates those signals in perl without emulating them<br/>in the C level - nothing an event loop can do about that, thats a limitation<br/>of at leats activestate perl.<br/><br/>&gt; I know the following is an incomplete report as it does not contain<br/>&gt; exact system information (in general, Solaris 5.8) and perl version (in<br/><br/>Since there is no solaris 5.8 version in existance, I guess you mean<br/>solaris 8 (that could make a difference as I only test on solaris 10).<br/><br/>&gt; * By the way, there *were* cases today when the signal was ignored<br/>&gt; completely, this time in a script where I had to add an explicit<br/>&gt; signal watcher to make it interruptable at all. I hope to shrink<br/>&gt; this down to a short demo script to send.<br/><br/>Indeed, that would be helpful.<br/><br/>However, are you sure you don&#39;t provide your own signal handlers via %SIG<br/>and you really have a signal handler installed for SIGINT? Either would<br/>actually perfectly explain the behaviour you are seeing. %SIG cannot work<br/>because in newer perls this is only handled when the perl interpreter gets<br/>control (which cannot be the case unless you run some watchers). The whole<br/>point of an event loop is to shield you from asynchronous signals, you<br/>have to embed them into the event loop (thats not specific to EV, other<br/>event loops work the same way).<br/><br/>If you cannot install signal handlers properly you could try to install a<br/>check watcher, which runs at every loop iteration, and hope that whoever<br/>installs its own signal handler doesn&#39;t make syscalls restartable, in<br/>which case you have lost anyways.<br/><br/>&gt; DB&lt;2&gt; $p=EV::periodic(0, 2, 0, sub {print &quot;Periodic call with short intervall at &quot;, time, &quot;.\n&quot;})<br/><br/>Here you store one reference into $p, the other is kept by the debugger.<br/><br/>&gt; DB&lt;&lt;4&gt;&gt; $p=EV::periodic(0, 20, 0, sub {print &quot;Periodic call with &gt; longer intervall at &quot;, time, &quot;.\n&quot;})<br/><br/>&gt; Periodic call with longer intervall at 1196850145.<br/>&gt; Periodic call with short intervall at 1196850145.<br/><br/>Since you only overwrote one reference here, both watchers are still<br/>active.<br/><br/>Watchers only get destroyed when _all_ refererences are broken, as with<br/>any other perl object (the same is true with Event, except that you<br/>additionally need an additional explicit cancel call with Event).<br/><br/>&gt; was no further reference to the first watcher object. But when running<br/>&gt; the loop again *both* watchers were present.<br/><br/>Yup, because both are alive.<br/><br/>Try outside the debugger, that will be less confusing (also, it would help<br/>if you wouldn&#39;t wrap codelines in your emails :).<br/><br/>Try e.g.:<br/><br/> use EV;<br/><br/> $p=EV::periodic(0, 2, 0, sub {print &quot;Periodic call with short intervall at &quot;, EV::now, &quot;.\n&quot;});<br/> $t = EV::timer 3,0,sub { EV::unloop };<br/><br/> EV::loop;<br/><br/> $p = EV::periodic(0, 20, 0, sub {print &quot;Periodic call with longer intervall at &quot;, EV::now, &quot;.\n&quot;});<br/><br/> EV::loop;<br/><br/>Here it is easy to see when values get destroyed.<br/><br/>As an additional hint, you should give EV::now a try: it is faster then<br/>time (no syscall) and more accurate in the sense that it returns the event<br/>timestamp (while time returns the current time, which might or might not<br/>be what you are interested in).<br/><br/>&gt; Finally, in both traces one sees a first callback invocation that does<br/>&gt; not fit into the periodic scheme.<br/><br/>That &quot;one&quot; must have rather magical abilities to see anything when you<br/>round your time and do not use the event time but some other time :-&gt;<br/>Try using EV::now and you will see that the timestamps are actually<br/>correct. Here are a few sample runs with both EV::now and time to<br/>elaborate this:<br/><br/> cerebro /tmp# perl x.pl<br/> Periodic call with short intervall at 1196906694.00098 1196906693.<br/> Periodic call with longer intervall at 1196906700.00108 1196906699.<br/><br/> cerebro /tmp# perl x.pl<br/> Periodic call with short intervall at 1196906706.00513 1196906706.<br/> Periodic call with short intervall at 1196906708.00117 1196906707.<br/> Periodic call with longer intervall at 1196906720.00134 1196906719.<br/> Periodic call with longer intervall at 1196906740.0056 1196906739.<br/><br/>You could alternatively use Time::Hires, which also doesn&#39;t round:<br/><br/> cerebro /tmp# perl x.pl<br/> Periodic call with short intervall at 1196906782.00217 1196906782.00224.<br/> Periodic call with short intervall at 1196906784.00219 1196906784.00222.<br/><br/> cerebro /tmp# perl x.pl<br/> Periodic call with short intervall at 1196906796.00233 1196906796.00241.<br/> Periodic call with longer intervall at 1196906800.00238 1196906800.00242.<br/> Periodic call with longer intervall at 1196906820.00265 1196906820.00268.<br/><br/>In any case, you would see the same behaviour with Event, as it uses<br/>Time::HiRes internally and is therefore also more accurate than time().<br/><br/>&gt; I am not sure when I wil have time to send a demo script for the<br/>&gt; mentioned case of an ignored interrupt but I hope the traces give you a<br/>&gt; first impression.<br/><br/>So far, it seems everything works right. While EV is young and certainly<br/>has some bugs, it is used in a lot of projects, and really can&#39;t be<br/>_totally_ broken.<br/><br/>So, when you see totally off behaviour like above, first give your test<br/>script a bit of thinking, and try to find out wether your test actually<br/>can give accurate results (a good example where you should is the time<br/>call and your conclusion that its resolution must be enough to actually<br/>check the scheduling accuracy of EV, while forgetting that its resolution<br/>is very bad indeed).<br/><br/>That keeps adrenaline levels down on all sides :)<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/2007/12/msg1092.html Wed, 05 Dec 2007 18:21:35 +0000 Re: Replacement of Event with EV by Marc Lehmann On Wed, Dec 05, 2007 at 05:40:47PM -0700, Rusty Conover &lt;rconover@infogears.com&gt; wrote:<br/>&gt; I&#39;m looking into using EV rather then Event for my needs but it seems <br/>&gt; the I/O timers don&#39;t have a nice way to schedule both a timeout and a <br/>&gt; I/O callback at the same time into the same callback.<br/><br/>Thats a feature, and compared to Event, actually a bugfix.<br/><br/>&gt; Such as setting the timeout parameter to the IO watcher.<br/>&gt; <br/>&gt; Is this just my oversight or a design decision?<br/><br/>Its a design decision. Combining timers with io watchers is unnatural,<br/>because:<br/><br/>- you often don&#39;t need both, so shouldn&#39;t be forced to pay for them<br/>- you can&#39;t choose the type of timeout (event only has absolute timers<br/> anyways, though, which are unsuitable for many tasks such as idle timeouts<br/> for i/o, where you need relative timeouts).<br/>- you have to manage two timeouts or weirder stuff when you have<br/> two separate i/o watchers, or use a third watcher (paying even more).<br/>- it is often unclear on which events exactly the timeout gets reset<br/> (if at all), and even if not, there is no flexibility (how do you<br/> chose between an idle timeout and an overall timeout<br/> for completion with Event? you cannot).<br/><br/>As it is trivial to create a separate timeout (and much faster than with<br/>Event, too), there is no drawback to this design.<br/><br/>It also usually leads to smaller and simpler code, once one understands<br/>ones own needs...<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/2007/12/msg1091.html Wed, 05 Dec 2007 17:19:43 +0000 Replacement of Event with EV by Rusty Conover I&#39;m looking into using EV rather then Event for my needs but it seems <br/>the I/O timers don&#39;t have a nice way to schedule both a timeout and a <br/>I/O callback at the same time into the same callback.<br/><br/>Such as setting the timeout parameter to the IO watcher.<br/><br/>Is this just my oversight or a design decision?<br/><br/>Thanks,<br/><br/>Rusty<br/><br/> http://www.nntp.perl.org/group/perl.loop/2007/12/msg1090.html Wed, 05 Dec 2007 16:40:58 +0000 Re: announcing the new EV module, a modern redesign of Event by Jochen Stenzel <br/>Hello Marc,<br/><br/>&gt;&gt; Then I run a simple loop in the debugger (on the same system), with just<br/>&gt;&gt; one periodic watcher. Surprisingly, once started I could not interrupt<br/>&gt;&gt; the loop via CTRL-C.<br/>&gt; <br/>&gt; That is interesting. I am not aware that solaris event ports would block<br/>&gt; any signals, and in fatc, I cannot reproduce this. Are you sure that your<br/>&gt; tty settings actually do anything with CTRL-C (such as sending an INT)?<br/><br/>I am - I retried it today, other programs receive the signal and the<br/>effect is the same if I send the signal via kill from another terminal.<br/><br/>I know the following is an incomplete report as it does not contain<br/>exact system information (in general, Solaris 5.8) and perl version (in<br/>general, 5.8.6 without thread support), but today the picture was a bit<br/>different:<br/><br/>* I *could* stop the loop in the debugger today, but it took a while:<br/><br/> DB&lt;2&gt; sub d {print &quot;===&gt; TIME: &quot;, time, &quot;\n&quot;;}<br/><br/> DB&lt;3&gt; d<br/>===&gt; TIME: 1196849803<br/><br/> DB&lt;4&gt; use EV<br/><br/> DB&lt;5&gt; $p=EV::periodic(0, 10, 0, sub {print &quot;Periodic call at &quot;, time,<br/>&quot;.\n&quot;})<br/><br/> DB&lt;6&gt; d(); EV::loop<br/>===&gt; TIME: 1196849839<br/>Periodic call at 1196849839.<br/>Periodic call at 1196849840.<br/>Periodic call at 1196849850.<br/>Periodic call at 1196849860.<br/>Periodic call at 1196849870.<br/>^Cd<br/>Periodic call at 1196849880.<br/>EV::loop((eval 32)[.../perl5db.pl:628]:2):<br/>2:<br/> DB&lt;&lt;7&gt;&gt; d<br/>===&gt; TIME: 1196849890<br/><br/><br/><br/>* so, CTRL-C worked this time ...<br/>* ... but not immediately (as usual, instead it took until the next<br/> watcher event, plus the time to the next event check (as it seems)).<br/> This was verified with longer intervals and it was reproducable.<br/>* In contrast, with an additional signal watcher the signal is<br/> handled instantly.<br/>* By the way, there *were* cases today when the signal was ignored<br/> completely, this time in a script where I had to add an explicit<br/> signal watcher to make it interruptable at all. I hope to shrink<br/> this down to a short demo script to send.<br/><br/><br/>Another interesting effect you might be interested in was this:<br/><br/> DB&lt;1&gt; use EV<br/><br/> DB&lt;2&gt; $p=EV::periodic(0, 2, 0, sub {print &quot;Periodic call with short<br/>intervall at &quot;, time, &quot;.\n&quot;})<br/><br/> DB&lt;3&gt; EV::loop<br/>Periodic call with short intervall at 1196850121.<br/>Periodic call with short intervall at 1196850122.<br/>Periodic call with short intervall at 1196850124.<br/>Periodic call with short intervall at 1196850126.<br/>^CPeriodic call with short intervall at 1196850128.<br/>EV::loop((eval 23)[.../perl5db.pl:628]:2):<br/>2:<br/> DB&lt;&lt;4&gt;&gt; $p=EV::periodic(0, 20, 0, sub {print &quot;Periodic call with<br/>longer intervall at &quot;, time,<br/>&quot;.\n&quot;})<br/><br/> DB&lt;&lt;5&gt;&gt; EV::loop<br/>Periodic call with longer intervall at 1196850145.<br/>Periodic call with short intervall at 1196850145.<br/>Periodic call with short intervall at 1196850146.<br/>Periodic call with short intervall at 1196850148.<br/>Periodic call with short intervall at 1196850150.<br/>Periodic call with short intervall at 1196850152.<br/>Periodic call with short intervall at 1196850154.<br/>Periodic call with short intervall at 1196850156.<br/>Periodic call with short intervall at 1196850158.<br/>Periodic call with longer intervall at 1196850160.<br/>Periodic call with short intervall at 1196850160.<br/>^CPeriodic call with short intervall at 1196850162.<br/><br/><br/>So, a periodic watcher with a short interval was assigned to a variable,<br/>then the loop was started and interrupted via CTRL-C. After that a new<br/>watcher was installed and assigned to the same variable, which - as I<br/>understood the docs - should uninstall the first watcher as now there<br/>was no further reference to the first watcher object. But when running<br/>the loop again *both* watchers were present.<br/><br/><br/>Finally, in both traces one sees a first callback invocation that does<br/>not fit into the periodic scheme.<br/><br/><br/>I am not sure when I wil have time to send a demo script for the<br/>mentioned case of an ignored interrupt but I hope the traces give you a<br/>first impression.<br/><br/> Jochen<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> http://www.nntp.perl.org/group/perl.loop/2007/12/msg1089.html Wed, 05 Dec 2007 16:07:49 +0000