--- AnyEvent/README 2009/04/20 14:34:18 1.37 +++ AnyEvent/README 2009/06/23 23:37:32 1.40 @@ -1,27 +1,34 @@ NAME AnyEvent - provide framework for multiple event loops - EV, Event, Glib, Tk, Perl, Event::Lib, Qt, POE - various supported event - loops + EV, Event, Glib, Tk, Perl, Event::Lib, Qt and POE are various supported + event loops. SYNOPSIS use AnyEvent; - my $w = AnyEvent->io (fh => $fh, poll => "r|w", cb => sub { ... }); + # file descriptor readable + my $w = AnyEvent->io (fh => $fh, poll => "r", cb => sub { ... }); + # one-shot or repeating timers my $w = AnyEvent->timer (after => $seconds, cb => sub { ... }); my $w = AnyEvent->timer (after => $seconds, interval => $seconds, cb => ... print AnyEvent->now; # prints current event loop time print AnyEvent->time; # think Time::HiRes::time or simply CORE::time. + # POSIX signal my $w = AnyEvent->signal (signal => "TERM", cb => sub { ... }); + # child process exit my $w = AnyEvent->child (pid => $pid, cb => sub { my ($pid, $status) = @_; ... }); + # called when event loop idle (if applicable) + my $w = AnyEvent->idle (cb => sub { ... }); + my $w = AnyEvent->condvar; # stores whether a condition was flagged $w->send; # wake up current and all future recv's $w->recv; # enters "main loop" till $condvar gets ->send @@ -387,10 +394,10 @@ Example: fork a process and wait for it my $done = AnyEvent->condvar; - - my $pid = fork or exit 5; - - my $w = AnyEvent->child ( + + my $pid = fork or exit 5; + + my $w = AnyEvent->child ( pid => $pid, cb => sub { my ($pid, $status) = @_; @@ -398,10 +405,44 @@ $done->send; }, ); - - # do something else, then wait for process exit + + # do something else, then wait for process exit $done->recv; + IDLE WATCHERS + Sometimes there is a need to do something, but it is not so important to + do it instantly, but only when there is nothing better to do. This + "nothing better to do" is usually defined to be "no other events need + attention by the event loop". + + Idle watchers ideally get invoked when the event loop has nothing better + to do, just before it would block the process to wait for new events. + Instead of blocking, the idle watcher is invoked. + + Most event loops unfortunately do not really support idle watchers (only + EV, Event and Glib do it in a usable fashion) - for the rest, AnyEvent + will simply call the callback "from time to time". + + Example: read lines from STDIN, but only process them when the program + is otherwise idle: + + my @lines; # read data + my $idle_w; + my $io_w = AnyEvent->io (fh => \*STDIN, poll => 'r', cb => sub { + push @lines, scalar ; + + # start an idle watcher, if not already done + $idle_w ||= AnyEvent->idle (cb => sub { + # handle only one line, when there are lines left + if (my $line = shift @lines) { + print "handled when idle: $line"; + } else { + # otherwise disable the idle watcher again + undef $idle_w; + } + }); + }); + CONDITION VARIABLES If you are familiar with some event loops you will know that all of them require you to run some blocking "loop", "run" or similar function that @@ -844,7 +885,11 @@ ENVIRONMENT VARIABLES The following environment variables are used by this module or its - submodules: + submodules. + + Note that AnyEvent will remove *all* environment variables starting with + "PERL_ANYEVENT_" from %ENV when it is loaded while taint mode is + enabled. "PERL_ANYEVENT_VERBOSE" By default, AnyEvent will be completely silent except in fatal @@ -1359,6 +1404,64 @@ * C-based event loops perform very well with small number of watchers, as the management overhead dominates. + THE IO::Lambda BENCHMARK + Recently I was told about the benchmark in the IO::Lambda manpage, which + could be misinterpreted to make AnyEvent look bad. In fact, the + benchmark simply compares IO::Lambda with POE, and IO::Lambda looks + better (which shouldn't come as a surprise to anybody). As such, the + benchmark is fine, and shows that the AnyEvent backend from IO::Lambda + isn't very optimal. But how would AnyEvent compare when used without the + extra baggage? To explore this, I wrote the equivalent benchmark for + AnyEvent. + + The benchmark itself creates an echo-server, and then, for 500 times, + connects to the echo server, sends a line, waits for the reply, and then + creates the next connection. This is a rather bad benchmark, as it + doesn't test the efficiency of the framework, but it is a benchmark + nevertheless. + + name runtime + Lambda/select 0.330 sec + + optimized 0.122 sec + Lambda/AnyEvent 0.327 sec + + optimized 0.138 sec + Raw sockets/select 0.077 sec + POE/select, components 0.662 sec + POE/select, raw sockets 0.226 sec + POE/select, optimized 0.404 sec + + AnyEvent/select/nb 0.085 sec + AnyEvent/EV/nb 0.068 sec + +state machine 0.134 sec + + The benchmark is also a bit unfair (my fault) - the IO::Lambda + benchmarks actually make blocking connects and use 100% blocking I/O, + defeating the purpose of an event-based solution. All of the newly + written AnyEvent benchmarks use 100% non-blocking connects (using + AnyEvent::Socket::tcp_connect and the asynchronous pure perl DNS + resolver), so AnyEvent is at a disadvantage here as non-blocking + connects generally require a lot more bookkeeping and event handling + than blocking connects (which involve a single syscall only). + + The last AnyEvent benchmark additionally uses AnyEvent::Handle, which + offers similar expressive power as POE and IO::Lambda (using + conventional Perl syntax), which means both the echo server and the + client are 100% non-blocking w.r.t. I/O, further placing it at a + disadvantage. + + As you can see, AnyEvent + EV even beats the hand-optimised "raw sockets + benchmark", while AnyEvent + its pure perl backend easily beats + IO::Lambda and POE. + + And even the 100% non-blocking version written using the high-level (and + slow :) AnyEvent::Handle abstraction beats both POE and IO::Lambda, even + thought it does all of DNS, tcp-connect and socket I/O in a non-blocking + way. + + The two AnyEvent benchmarks can be found as eg/ae0.pl and eg/ae2.pl in + the AnyEvent distribution, the remaining benchmarks are part of the + IO::lambda distribution and were used without any changes. + SIGNALS AnyEvent currently installs handlers for these signals: @@ -1403,13 +1506,13 @@ before the first watcher gets created, e.g. with a "BEGIN" block: BEGIN { delete $ENV{PERL_ANYEVENT_MODEL} } - - use AnyEvent; + + use AnyEvent; Similar considerations apply to $ENV{PERL_ANYEVENT_VERBOSE}, as that can be used to probe what backend is used and gain other information (which is probably even less useful to an attacker than PERL_ANYEVENT_MODEL), - and $ENV{PERL_ANYEGENT_STRICT}. + and $ENV{PERL_ANYEVENT_STRICT}. BUGS Perl 5.8 has numerous memleaks that sometimes hit this module and are