--- AnyEvent/README 2008/04/19 04:58:14 1.16 +++ AnyEvent/README 2008/04/28 08:02:14 1.19 @@ -1,8 +1,8 @@ NAME AnyEvent - provide framework for multiple event loops - EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl - various supported - event loops + EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl, Event::Lib, Qt, POE - + various supported event loops SYNOPSIS use AnyEvent; @@ -78,9 +78,11 @@ During the first call of any watcher-creation method, the module tries to detect the currently loaded event loop by probing whether one of the following modules is already loaded: Coro::EV, Coro::Event, EV, Event, - Glib, Tk. The first one found is used. If none are found, the module - tries to load these modules in the stated order. The first one that can - be successfully loaded will be used. If, after this, still none could be + Glib, AnyEvent::Impl::Perl, Tk, Event::Lib, Qt, POE. The first one found + is used. If none are found, the module tries to load these modules + (excluding Tk, Event::Lib, Qt and POE as the pure perl adaptor should + always succeed) in the order given. The first one that can be + successfully loaded will be used. If, after this, still none could be found, AnyEvent will fall back to a pure-perl event loop, which is not very efficient, but should work everywhere. @@ -131,7 +133,7 @@ my variables are only visible after the statement in which they are declared. - IO WATCHERS + I/O WATCHERS You can create an I/O watcher by calling the "AnyEvent->io" method with the following mandatory key-value pairs as arguments: @@ -140,11 +142,13 @@ watcher waiting for "r"eadable or "w"ritable events, respectively. "cb" is the callback to invoke each time the file handle becomes ready. - File handles will be kept alive, so as long as the watcher exists, the - file handle exists, too. - - It is not allowed to close a file handle as long as any watcher is - active on the underlying file descriptor. + Although the callback might get passed parameters, their value and + presence is undefined and you cannot rely on them. Portable AnyEvent + callbacks cannot use arguments passed to I/O watcher callbacks. + + The I/O watcher might use the underlying file descriptor or a copy of + it. You must not close a file handle as long as any watcher is active on + the underlying file descriptor. Some event loops issue spurious readyness notifications, so you should always use non-blocking calls when reading/writing from/to your file @@ -164,8 +168,12 @@ with the following mandatory arguments: "after" specifies after how many seconds (fractional values are - supported) should the timer activate. "cb" the callback to invoke in - that case. + supported) the callback should be invoked. "cb" is the callback to + invoke in that case. + + Although the callback might get passed parameters, their value and + presence is undefined and you cannot rely on them. Portable AnyEvent + callbacks cannot use arguments passed to time watcher callbacks. The timer callback will be invoked at most once: if you want a repeating timer you have to create a new watcher (this is a limitation by both Tk @@ -202,12 +210,14 @@ While most event loops expect timers to specified in a relative way, they use absolute time internally. This makes a difference when your clock "jumps", for example, when ntp decides to set your clock backwards - from the wrong 2014-01-01 to 2008-01-01, a watcher that you created to - fire "after" a second might actually take six years to finally fire. + from the wrong date of 2014-01-01 to 2008-01-01, a watcher that is + supposed to fire "after" a second might actually take six years to + finally fire. AnyEvent cannot compensate for this. The only event loop that is conscious about these issues is EV, which offers both relative - (ev_timer) and absolute (ev_periodic) timers. + (ev_timer, based on true relative time) and absolute (ev_periodic, based + on wallclock time) timers. AnyEvent always prefers relative timers, if available, matching the AnyEvent API. @@ -217,7 +227,11 @@ *name* without any "SIG" prefix, "cb" is the Perl callback to be invoked whenever a signal occurs. - Multiple signals occurances can be clumped together into one callback + Although the callback might get passed parameters, their value and + presence is undefined and you cannot rely on them. Portable AnyEvent + callbacks cannot use arguments passed to signal watcher callbacks. + + Multiple signal occurances can be clumped together into one callback invocation, and callback invocation will be synchronous. synchronous means that it might take a while until the signal gets handled by the process, but it is guarenteed not to interrupt any other callbacks. @@ -239,18 +253,42 @@ watches for any child process exit). The watcher will trigger as often as status change for the child are received. This works by installing a signal handler for "SIGCHLD". The callback will be called with the pid - and exit status (as returned by waitpid). + and exit status (as returned by waitpid), so unlike other watcher types, + you *can* rely on child watcher callback arguments. + + There is a slight catch to child watchers, however: you usually start + them *after* the child process was created, and this means the process + could have exited already (and no SIGCHLD will be sent anymore). + + Not all event models handle this correctly (POE doesn't), but even for + event models that *do* handle this correctly, they usually need to be + loaded before the process exits (i.e. before you fork in the first + place). + + This means you cannot create a child watcher as the very first thing in + an AnyEvent program, you *have* to create at least one watcher before + you "fork" the child (alternatively, you can call "AnyEvent::detect"). + + Example: fork a process and wait for it + + my $done = AnyEvent->condvar; + + AnyEvent::detect; # force event module to be initialised - Example: wait for pid 1333 + my $pid = fork or exit 5; my $w = AnyEvent->child ( - pid => 1333, + pid => $pid, cb => sub { my ($pid, $status) = @_; warn "pid $pid exited with status $status"; + $done->broadcast; }, ); + # do something else, then wait for process exit + $done->wait; + CONDITION VARIABLES Condition variables can be created by calling the "AnyEvent->condvar" method without any arguments. @@ -334,11 +372,24 @@ AnyEvent::Impl::CoroEV based on Coro::EV, best choice. AnyEvent::Impl::CoroEvent based on Coro::Event, second best choice. - AnyEvent::Impl::EV based on EV (an interface to libev, also best choice). - AnyEvent::Impl::Event based on Event, also second best choice :) + AnyEvent::Impl::EV based on EV (an interface to libev, best choice). + AnyEvent::Impl::Event based on Event, second best choice. AnyEvent::Impl::Glib based on Glib, third-best choice. - AnyEvent::Impl::Tk based on Tk, very bad choice. AnyEvent::Impl::Perl pure-perl implementation, inefficient but portable. + AnyEvent::Impl::Tk based on Tk, very bad choice. + AnyEvent::Impl::Qt based on Qt, cannot be autoprobed (see its docs). + AnyEvent::Impl::EventLib based on Event::Lib, leaks memory and worse. + AnyEvent::Impl::POE based on POE, not generic enough for full support. + + There is no support for WxWidgets, as WxWidgets has no support for + watching file handles. However, you can use WxWidgets through the + POE Adaptor, as POE has a Wx backend that simply polls 20 times per + second, which was considered to be too horrible to even consider for + AnyEvent. Likewise, other POE backends can be used by AnyEvent by + using it's adaptor. + + AnyEvent knows about Prima and Wx and will try to use POE when + autodetecting them. AnyEvent::detect Returns $AnyEvent::MODEL, forcing autodetection of the event model @@ -387,6 +438,61 @@ loading the "AnyEvent::Impl::Perl" module, which gives you similar behaviour everywhere, but letting AnyEvent chose is generally better. +OTHER MODULES + The following is a non-exhaustive list of additional modules that use + AnyEvent and can therefore be mixed easily with other AnyEvent modules + in the same program. Some of the modules come with AnyEvent, some are + available via CPAN. + + AnyEvent::Util + Contains various utility functions that replace often-used but + blocking functions such as "inet_aton" by event-/callback-based + versions. + + AnyEvent::Handle + Provide read and write buffers and manages watchers for reads and + writes. + + AnyEvent::Socket + Provides a means to do non-blocking connects, accepts etc. + + AnyEvent::HTTPD + Provides a simple web application server framework. + + AnyEvent::DNS + Provides asynchronous DNS resolver capabilities, beyond what + AnyEvent::Util offers. + + AnyEvent::FastPing + The fastest ping in the west. + + Net::IRC3 + AnyEvent based IRC client module family. + + Net::XMPP2 + AnyEvent based XMPP (Jabber protocol) module family. + + Net::FCP + AnyEvent-based implementation of the Freenet Client Protocol, + birthplace of AnyEvent. + + Event::ExecFlow + High level API for event-based execution flow control. + + Coro + Has special support for AnyEvent. + + IO::Lambda + The lambda approach to I/O - don't ask, look there. Can use + AnyEvent. + + IO::AIO + Truly asynchronous I/O, should be in the toolbox of every event + programmer. Can be trivially made to use AnyEvent. + + BDB Truly asynchronous Berkeley DB access. Can be trivially made to use + AnyEvent. + SUPPLYING YOUR OWN EVENT MODEL INTERFACE This is an advanced topic that you do not normally need to use AnyEvent in a module. This section is only of use to event loop authors who want @@ -433,11 +539,35 @@ ENVIRONMENT VARIABLES The following environment variables are used by this module: - "PERL_ANYEVENT_VERBOSE" when set to 2 or higher, cause AnyEvent to - report to STDERR which event model it chooses. + "PERL_ANYEVENT_VERBOSE" + By default, AnyEvent will be completely silent except in fatal + conditions. You can set this environment variable to make AnyEvent + more talkative. + + When set to 1 or higher, causes AnyEvent to warn about unexpected + conditions, such as not being able to load the event model specified + by "PERL_ANYEVENT_MODEL". + + When set to 2 or higher, cause AnyEvent to report to STDERR which + event model it chooses. + + "PERL_ANYEVENT_MODEL" + This can be used to specify the event model to be used by AnyEvent, + before autodetection and -probing kicks in. It must be a string + consisting entirely of ASCII letters. The string "AnyEvent::Impl::" + gets prepended and the resulting module name is loaded and if the + load was successful, used as event model. If it fails to load + AnyEvent will proceed with autodetection and -probing. + + This functionality might change in future versions. + + For example, to force the pure perl model (AnyEvent::Impl::Perl) you + could start your program like this: + + PERL_ANYEVENT_MODEL=Perl perl ... EXAMPLE PROGRAM - The following program uses an IO watcher to read data from STDIN, a + The following program uses an I/O watcher to read data from STDIN, a timer to display a message once per second, and a condition variable to quit the program when the user enters quit: @@ -590,14 +720,277 @@ $quit->wait; +BENCHMARKS + To give you an idea of the performance and overheads that AnyEvent adds + over the event loops themselves and to give you an impression of the + speed of various event loops I prepared some benchmarks. + + BENCHMARKING ANYEVENT OVERHEAD + Here is a benchmark of various supported event models used natively and + through anyevent. The benchmark creates a lot of timers (with a zero + timeout) and I/O watchers (watching STDOUT, a pty, to become writable, + which it is), lets them fire exactly once and destroys them again. + + Source code for this benchmark is found as eg/bench in the AnyEvent + distribution. + + Explanation of the columns + *watcher* is the number of event watchers created/destroyed. Since + different event models feature vastly different performances, each event + loop was given a number of watchers so that overall runtime is + acceptable and similar between tested event loop (and keep them from + crashing): Glib would probably take thousands of years if asked to + process the same number of watchers as EV in this benchmark. + + *bytes* is the number of bytes (as measured by the resident set size, + RSS) consumed by each watcher. This method of measuring captures both C + and Perl-based overheads. + + *create* is the time, in microseconds (millionths of seconds), that it + takes to create a single watcher. The callback is a closure shared + between all watchers, to avoid adding memory overhead. That means + closure creation and memory usage is not included in the figures. + + *invoke* is the time, in microseconds, used to invoke a simple callback. + The callback simply counts down a Perl variable and after it was invoked + "watcher" times, it would "->broadcast" a condvar once to signal the end + of this phase. + + *destroy* is the time, in microseconds, that it takes to destroy a + single watcher. + + Results + name watchers bytes create invoke destroy comment + EV/EV 400000 244 0.56 0.46 0.31 EV native interface + EV/Any 100000 244 2.50 0.46 0.29 EV + AnyEvent watchers + CoroEV/Any 100000 244 2.49 0.44 0.29 coroutines + Coro::Signal + Perl/Any 100000 513 4.92 0.87 1.12 pure perl implementation + Event/Event 16000 516 31.88 31.30 0.85 Event native interface + Event/Any 16000 590 35.75 31.42 1.08 Event + AnyEvent watchers + Glib/Any 16000 1357 98.22 12.41 54.00 quadratic behaviour + Tk/Any 2000 1860 26.97 67.98 14.00 SEGV with >> 2000 watchers + POE/Event 2000 6644 108.64 736.02 14.73 via POE::Loop::Event + POE/Select 2000 6343 94.13 809.12 565.96 via POE::Loop::Select + + Discussion + The benchmark does *not* measure scalability of the event loop very + well. For example, a select-based event loop (such as the pure perl one) + can never compete with an event loop that uses epoll when the number of + file descriptors grows high. In this benchmark, all events become ready + at the same time, so select/poll-based implementations get an unnatural + speed boost. + + Also, note that the number of watchers usually has a nonlinear effect on + overall speed, that is, creating twice as many watchers doesn't take + twice the time - usually it takes longer. This puts event loops tested + with a higher number of watchers at a disadvantage. + + To put the range of results into perspective, consider that on the + benchmark machine, handling an event takes roughly 1600 CPU cycles with + EV, 3100 CPU cycles with AnyEvent's pure perl loop and almost 3000000 + CPU cycles with POE. + + "EV" is the sole leader regarding speed and memory use, which are both + maximal/minimal, respectively. Even when going through AnyEvent, it uses + far less memory than any other event loop and is still faster than Event + natively. + + The pure perl implementation is hit in a few sweet spots (both the + constant timeout and the use of a single fd hit optimisations in the + perl interpreter and the backend itself). Nevertheless this shows that + it adds very little overhead in itself. Like any select-based backend + its performance becomes really bad with lots of file descriptors (and + few of them active), of course, but this was not subject of this + benchmark. + + The "Event" module has a relatively high setup and callback invocation + cost, but overall scores in on the third place. + + "Glib"'s memory usage is quite a bit higher, but it features a faster + callback invocation and overall ends up in the same class as "Event". + However, Glib scales extremely badly, doubling the number of watchers + increases the processing time by more than a factor of four, making it + completely unusable when using larger numbers of watchers (note that + only a single file descriptor was used in the benchmark, so + inefficiencies of "poll" do not account for this). + + The "Tk" adaptor works relatively well. The fact that it crashes with + more than 2000 watchers is a big setback, however, as correctness takes + precedence over speed. Nevertheless, its performance is surprising, as + the file descriptor is dup()ed for each watcher. This shows that the + dup() employed by some adaptors is not a big performance issue (it does + incur a hidden memory cost inside the kernel which is not reflected in + the figures above). + + "POE", regardless of underlying event loop (whether using its pure perl + select-based backend or the Event module, the POE-EV backend couldn't be + tested because it wasn't working) shows abysmal performance and memory + usage: Watchers use almost 30 times as much memory as EV watchers, and + 10 times as much memory as Event (the high memory requirements are + caused by requiring a session for each watcher). Watcher invocation + speed is almost 900 times slower than with AnyEvent's pure perl + implementation. The design of the POE adaptor class in AnyEvent can not + really account for this, as session creation overhead is small compared + to execution of the state machine, which is coded pretty optimally + within AnyEvent::Impl::POE. POE simply seems to be abysmally slow. + + Summary + * Using EV through AnyEvent is faster than any other event loop (even + when used without AnyEvent), but most event loops have acceptable + performance with or without AnyEvent. + + * The overhead AnyEvent adds is usually much smaller than the overhead + of the actual event loop, only with extremely fast event loops such + as EV adds AnyEvent significant overhead. + + * You should avoid POE like the plague if you want performance or + reasonable memory usage. + + BENCHMARKING THE LARGE SERVER CASE + This benchmark atcually benchmarks the event loop itself. It works by + creating a number of "servers": each server consists of a socketpair, a + timeout watcher that gets reset on activity (but never fires), and an + I/O watcher waiting for input on one side of the socket. Each time the + socket watcher reads a byte it will write that byte to a random other + "server". + + The effect is that there will be a lot of I/O watchers, only part of + which are active at any one point (so there is a constant number of + active fds for each loop iterstaion, but which fds these are is random). + The timeout is reset each time something is read because that reflects + how most timeouts work (and puts extra pressure on the event loops). + + In this benchmark, we use 10000 socketpairs (20000 sockets), of which + 100 (1%) are active. This mirrors the activity of large servers with + many connections, most of which are idle at any one point in time. + + Source code for this benchmark is found as eg/bench2 in the AnyEvent + distribution. + + Explanation of the columns + *sockets* is the number of sockets, and twice the number of "servers" + (as each server has a read and write socket end). + + *create* is the time it takes to create a socketpair (which is + nontrivial) and two watchers: an I/O watcher and a timeout watcher. + + *request*, the most important value, is the time it takes to handle a + single "request", that is, reading the token from the pipe and + forwarding it to another server. This includes deleting the old timeout + and creating a new one that moves the timeout into the future. + + Results + name sockets create request + EV 20000 69.01 11.16 + Perl 20000 73.32 35.87 + Event 20000 212.62 257.32 + Glib 20000 651.16 1896.30 + POE 20000 349.67 12317.24 uses POE::Loop::Event + + Discussion + This benchmark *does* measure scalability and overall performance of the + particular event loop. + + EV is again fastest. Since it is using epoll on my system, the setup + time is relatively high, though. + + Perl surprisingly comes second. It is much faster than the C-based event + loops Event and Glib. + + Event suffers from high setup time as well (look at its code and you + will understand why). Callback invocation also has a high overhead + compared to the "$_->() for .."-style loop that the Perl event loop + uses. Event uses select or poll in basically all documented + configurations. + + Glib is hit hard by its quadratic behaviour w.r.t. many watchers. It + clearly fails to perform with many filehandles or in busy servers. + + POE is still completely out of the picture, taking over 1000 times as + long as EV, and over 100 times as long as the Perl implementation, even + though it uses a C-based event loop in this case. + + Summary + * The pure perl implementation performs extremely well, considering + that it uses select. + + * Avoid Glib or POE in large projects where performance matters. + + BENCHMARKING SMALL SERVERS + While event loops should scale (and select-based ones do not...) even to + large servers, most programs we (or I :) actually write have only a few + I/O watchers. + + In this benchmark, I use the same benchmark program as in the large + server case, but it uses only eight "servers", of which three are active + at any one time. This should reflect performance for a small server + relatively well. + + The columns are identical to the previous table. + + Results + name sockets create request + EV 16 20.00 6.54 + Perl 16 25.75 12.62 + Event 16 81.27 35.86 + Glib 16 32.63 15.48 + POE 16 261.87 276.28 uses POE::Loop::Event + + Discussion + The benchmark tries to test the performance of a typical small server. + While knowing how various event loops perform is interesting, keep in + mind that their overhead in this case is usually not as important, due + to the small absolute number of watchers (that is, you need efficiency + and speed most when you have lots of watchers, not when you only have a + few of them). + + EV is again fastest. + + Perl again comes second. It is noticably faster than the C-based event + loops Event and Glib, although the difference is too small to really + matter. + + POE also performs much better in this case, but is is still far behind + the others. + + Summary + * C-based event loops perform very well with small number of watchers, + as the management overhead dominates. + +FORK + Most event libraries are not fork-safe. The ones who are usually are + because they are so inefficient. Only EV is fully fork-aware. + + If you have to fork, you must either do so *before* creating your first + watcher OR you must not use AnyEvent at all in the child. + +SECURITY CONSIDERATIONS + AnyEvent can be forced to load any event model via + $ENV{PERL_ANYEVENT_MODEL}. While this cannot (to my knowledge) be used + to execute arbitrary code or directly gain access, it can easily be used + to make the program hang or malfunction in subtle ways, as AnyEvent + watchers will not be active when the program uses a different event + model than specified in the variable. + + You can make AnyEvent completely ignore this variable by deleting it + before the first watcher gets created, e.g. with a "BEGIN" block: + + BEGIN { delete $ENV{PERL_ANYEVENT_MODEL} } + + use AnyEvent; + SEE ALSO Event modules: Coro::EV, EV, EV::Glib, Glib::EV, Coro::Event, Event, - Glib::Event, Glib, Coro, Tk. + Glib::Event, Glib, Coro, Tk, Event::Lib, Qt, POE. Implementations: AnyEvent::Impl::CoroEV, AnyEvent::Impl::EV, AnyEvent::Impl::CoroEvent, AnyEvent::Impl::Event, AnyEvent::Impl::Glib, - AnyEvent::Impl::Tk, AnyEvent::Impl::Perl. + AnyEvent::Impl::Tk, AnyEvent::Impl::Perl, AnyEvent::Impl::EventLib, + AnyEvent::Impl::Qt, AnyEvent::Impl::POE. Nontrivial usage examples: Net::FCP, Net::XMPP2. +AUTHOR + Marc Lehmann + http://home.schmorp.de/