--- AnyEvent/README 2008/04/24 09:13:26 1.18 +++ AnyEvent/README 2008/04/28 08:02:14 1.19 @@ -1,7 +1,7 @@ NAME AnyEvent - provide framework for multiple event loops - EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl, Event::Lib, Qt - + EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl, Event::Lib, Qt, POE - various supported event loops SYNOPSIS @@ -78,12 +78,13 @@ 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, Event::Lib, Qt. The first one found is used. If none are - found, the module tries to load these modules (excluding Event::Lib and - Qt) 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. + 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. Because AnyEvent first checks for modules that are already loaded, loading an event model explicitly before first using AnyEvent will @@ -132,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: @@ -141,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. - As long as the I/O watcher exists it will keep the file descriptor or a - copy of it alive/open. - - 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 @@ -165,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 @@ -220,6 +227,10 @@ *name* without any "SIG" prefix, "cb" is the Perl callback to be invoked whenever a signal occurs. + 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 @@ -242,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; - Example: wait for pid 1333 + AnyEvent::detect; # force event module to be initialised + + 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. @@ -340,10 +375,21 @@ 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 @@ -392,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 @@ -439,6 +540,14 @@ The following environment variables are used by this module: "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. @@ -458,7 +567,7 @@ 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: @@ -611,6 +720,243 @@ $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. @@ -635,12 +981,12 @@ SEE ALSO Event modules: Coro::EV, EV, EV::Glib, Glib::EV, Coro::Event, Event, - Glib::Event, Glib, Coro, Tk, Event::Lib, Qt. + 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::EventLib, - AnyEvent::Impl::Qt. + AnyEvent::Impl::Qt, AnyEvent::Impl::POE. Nontrivial usage examples: Net::FCP, Net::XMPP2.