--- AnyEvent/lib/AnyEvent.pm 2008/04/27 19:15:43 1.100 +++ AnyEvent/lib/AnyEvent.pm 2008/05/01 12:35:54 1.105 @@ -68,26 +68,6 @@ useful) and you want to force your users to use the one and only event model, you should I use this module. -#TODO# - -Net::IRC3 -AnyEvent::HTTPD -AnyEvent::DNS -IO::AnyEvent -Net::FPing -Net::XMPP2 -Coro - -AnyEvent::IRC -AnyEvent::HTTPD -AnyEvent::DNS -AnyEvent::Handle -AnyEvent::Socket -AnyEvent::FPing -AnyEvent::XMPP -AnyEvent::SNMP -Coro - =head1 DESCRIPTION L provides an identical interface to multiple event loops. This @@ -319,39 +299,175 @@ =head2 CONDITION VARIABLES -Condition variables can be created by calling the C<< AnyEvent->condvar >> -method without any arguments. +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 +will actively watch for new events and call your callbacks. + +AnyEvent is different, it expects somebody else to run the event loop and +will only block when necessary (usually when told by the user). + +The instrument to do that is called a "condition variable", so called +because they represent a condition that must become true. + +Condition variables can be created by calling the C<< AnyEvent->condvar +>> method, usually without arguments. The only argument pair allowed is +C, which specifies a callback to be called when the condition variable +becomes true. + +After creation, the conditon variable is "false" until it becomes "true" +by calling the C method. + +Condition variables are similar to callbacks, except that you can +optionally wait for them. They can also be called merge points - points +in time where multiple outstandign events have been processed. And yet +another way to call them is transations - each condition variable can be +used to represent a transaction, which finishes at some point and delivers +a result. -A condition variable waits for a condition - precisely that the C<< -->broadcast >> method has been called. - -They are very useful to signal that a condition has been fulfilled, for -example, if you write a module that does asynchronous http requests, +Condition variables are very useful to signal that something has finished, +for example, if you write a module that does asynchronous http requests, then a condition variable would be the ideal candidate to signal the -availability of results. +availability of results. The user can either act when the callback is +called or can synchronously C<< ->wait >> for the results. -You can also use condition variables to block your main program until -an event occurs - for example, you could C<< ->wait >> in your main -program until the user clicks the Quit button in your app, which would C<< -->broadcast >> the "quit" event. +You can also use them to simulate traditional event loops - for example, +you can block your main program until an event occurs - for example, you +could C<< ->wait >> in your main program until the user clicks the Quit +button of your app, which would C<< ->broadcast >> the "quit" event. Note that condition variables recurse into the event loop - if you have -two pirces of code that call C<< ->wait >> in a round-robbin fashion, you +two pieces of code that call C<< ->wait >> in a round-robbin fashion, you lose. Therefore, condition variables are good to export to your caller, but you should avoid making a blocking wait yourself, at least in callbacks, as this asks for trouble. -This object has two methods: +Condition variables are represented by hash refs in perl, and the keys +used by AnyEvent itself are all named C<_ae_XXX> to make subclassing +easy (it is often useful to build your own transaction class on top of +AnyEvent). To subclass, use C as base class and call +it's C method in your own C method. + +There are two "sides" to a condition variable - the "producer side" which +eventually calls C<< -> broadcast >>, and the "consumer side", which waits +for the broadcast to occur. + +Example: + + # wait till the result is ready + my $result_ready = AnyEvent->condvar; + + # do something such as adding a timer + # or socket watcher the calls $result_ready->broadcast + # when the "result" is ready. + # in this case, we simply use a timer: + my $w = AnyEvent->timer ( + after => 1, + cb => sub { $result_ready->broadcast }, + ); + + # this "blocks" (while handling events) till the callback + # calls broadcast + $result_ready->wait; + +=head3 METHODS FOR PRODUCERS + +These methods should only be used by the producing side, i.e. the +code/module that eventually broadcasts the signal. Note that it is also +the producer side which creates the condvar in most cases, but it isn't +uncommon for the consumer to create it as well. =over 4 +=item $cv->broadcast (...) + +Flag the condition as ready - a running C<< ->wait >> and all further +calls to C will (eventually) return after this method has been +called. If nobody is waiting the broadcast will be remembered. + +If a callback has been set on the condition variable, it is called +immediately from within broadcast. + +Any arguments passed to the C call will be returned by all +future C<< ->wait >> calls. + +=item $cv->croak ($error) + +Similar to broadcast, but causes all call's wait C<< ->wait >> to invoke +C with the given error message/object/scalar. + +This can be used to signal any errors to the condition variable +user/consumer. + +=item $cv->begin ([group callback]) + +=item $cv->end + +These two methods can be used to combine many transactions/events into +one. For example, a function that pings many hosts in parallel might want +to use a condition variable for the whole process. + +Every call to C<< ->begin >> will increment a counter, and every call to +C<< ->end >> will decrement it. If the counter reaches C<0> in C<< ->end +>>, the (last) callback passed to C will be executed. That callback +is I to call C<< ->broadcast >>, but that is not required. If no +callback was set, C will be called without any arguments. + +Let's clarify this with the ping example: + + my $cv = AnyEvent->condvar; + + my %result; + $cv->begin (sub { $cv->broadcast (\%result) }); + + for my $host (@list_of_hosts) { + $cv->begin; + ping_host_then_call_callback $host, sub { + $result{$host} = ...; + $cv->end; + }; + } + + $cv->end; + +This code fragment supposedly pings a number of hosts and calls +C after results for all then have have been gathered - in any +order. To achieve this, the code issues a call to C when it starts +each ping request and calls C when it has received some result for +it. Since C and C only maintain a counter, the order in which +results arrive is not relevant. + +There is an additional bracketing call to C and C outside the +loop, which serves two important purposes: first, it sets the callback +to be called once the counter reaches C<0>, and second, it ensures that +broadcast is called even when C hosts are being pinged (the loop +doesn't execute once). + +This is the general pattern when you "fan out" into multiple subrequests: +use an outer C/C pair to set the callback and ensure C +is called at least once, and then, for each subrequest you start, call +C and for eahc subrequest you finish, call C. + +=back + +=head3 METHODS FOR CONSUMERS + +These methods should only be used by the consuming side, i.e. the +code awaits the condition. + =item $cv->wait -Wait (blocking if necessary) until the C<< ->broadcast >> method has been -called on c<$cv>, while servicing other watchers normally. +Wait (blocking if necessary) until the C<< ->broadcast >> or C<< ->croak +>> methods have been called on c<$cv>, while servicing other watchers +normally. + +You can only wait once on a condition - additional calls are valid but +will return immediately. + +If an error condition has been set by calling C<< ->croak >>, then this +function will call C. -You can only wait once on a condition - additional calls will return -immediately. +In list context, all parameters passed to C will be returned, +in scalar context only the first one will be returned. Not all event models support a blocking wait - some die in that case (programs might want to do that to stay interactive), so I explicitly support concurrent C<< ->wait >>'s from different coroutines, however). -=item $cv->broadcast - -Flag the condition as ready - a running C<< ->wait >> and all further -calls to C will (eventually) return after this method has been -called. If nobody is waiting the broadcast will be remembered.. +You can ensure that C<< -wait >> never blocks by setting a callback and +only calling C<< ->wait >> from within that callback (or at a later +time). This will work even when the event loop does not support blocking +waits otherwise. =back -Example: - - # wait till the result is ready - my $result_ready = AnyEvent->condvar; - - # do something such as adding a timer - # or socket watcher the calls $result_ready->broadcast - # when the "result" is ready. - # in this case, we simply use a timer: - my $w = AnyEvent->timer ( - after => 1, - cb => sub { $result_ready->broadcast }, - ); - - # this "blocks" (while handling events) till the watcher - # calls broadcast - $result_ready->wait; - =head1 GLOBAL VARIABLES AND FUNCTIONS =over 4 @@ -412,8 +509,8 @@ AnyEvent::Impl::CoroEvent based on Coro::Event, 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::Perl pure-perl implementation, fast and portable. AnyEvent::Impl::Glib based on Glib, third-best 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. @@ -481,24 +578,74 @@ =head1 OTHER MODULES -L itself comes with useful utility 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. -To make it easier to do non-blocking IO the modules L -and L are provided. L provides -read and write buffers and manages watchers for reads and writes. -L provides means to do non-blocking connects. +=over 4 -Aside from those there are these modules that support AnyEvent (and use it -for non-blocking IO): +=item L -=over 4 +Contains various utility functions that replace often-used but blocking +functions such as C by event-/callback-based versions. + +=item L + +Provide read and write buffers and manages watchers for reads and writes. + +=item L + +Provides a means to do non-blocking connects, accepts etc. + +=item L + +Provides a simple web application server framework. + +=item L + +Provides asynchronous DNS resolver capabilities, beyond what +L offers. =item L +The fastest ping in the west. + =item L +AnyEvent based IRC client module family. + =item L +AnyEvent based XMPP (Jabber protocol) module family. + +=item L + +AnyEvent-based implementation of the Freenet Client Protocol, birthplace +of AnyEvent. + +=item L + +High level API for event-based execution flow control. + +=item L + +Has special support for AnyEvent. + +=item L + +The lambda approach to I/O - don't ask, look there. Can use AnyEvent. + +=item L + +Truly asynchronous I/O, should be in the toolbox of every event +programmer. Can be trivially made to use AnyEvent. + +=item L + +Truly asynchronous Berkeley DB access. Can be trivially made to use +AnyEvent. + =back =cut @@ -525,12 +672,12 @@ [Coro::Event:: => AnyEvent::Impl::CoroEvent::], [EV:: => AnyEvent::Impl::EV::], [Event:: => AnyEvent::Impl::Event::], - [Glib:: => AnyEvent::Impl::Glib::], [Tk:: => AnyEvent::Impl::Tk::], [Wx:: => AnyEvent::Impl::POE::], [Prima:: => AnyEvent::Impl::POE::], [AnyEvent::Impl::Perl:: => AnyEvent::Impl::Perl::], # everything below here will not be autoprobed as the pureperl backend should work everywhere + [Glib:: => AnyEvent::Impl::Glib::], [Event::Lib:: => AnyEvent::Impl::EventLib::], # too buggy [Qt:: => AnyEvent::Impl::Qt::], # requires special main program [POE::Kernel:: => AnyEvent::Impl::POE::], # lasciate ogni speranza @@ -1043,17 +1190,22 @@ hidden memory cost inside the kernel which is not reflected in the figures above). -C, 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 +C, 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 with AnyEvent: 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 -L. POE simply seems to be abysmally slow. +implementation. + +The design of the POE adaptor class in AnyEvent can not really account +for the performance issues, though, as session creation overhead is +small compared to execution of the state machine, which is coded pretty +optimally within L (and while everybody agrees that +using multiple sessions is not a good approach, especially regarding +memory usage, even the author of POE could not come up with a faster +design). =head3 Summary @@ -1142,8 +1294,7 @@ =over 4 -=item * The pure perl implementation performs extremely well, considering -that it uses select. +=item * The pure perl implementation performs extremely well. =item * Avoid Glib or POE in large projects where performance matters. @@ -1182,12 +1333,9 @@ EV is again fastest. -The C-based event loops Event and Glib come in second this time, as the -overhead of running an iteration is much smaller in C than in Perl (little -code to execute in the inner loop, and perl's function calling overhead is -high, and updating all the data structures is costly). - -The pure perl event loop is much slower, but still competitive. +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. @@ -1205,7 +1353,8 @@ =head1 FORK Most event libraries are not fork-safe. The ones who are usually are -because they are so inefficient. Only L is fully fork-aware. +because they rely on inefficient but fork-safe C