AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Intro.pod view on Meta::CPAN
=encoding utf-8
=head1 NAME
AnyEvent::Intro - an introductory tutorial to AnyEvent
=head1 Introduction to AnyEvent
This is a tutorial that will introduce you to the features of AnyEvent.
The first part introduces the core AnyEvent module (after swamping you a
bit in evangelism), which might already provide all you ever need: If you
are only interested in AnyEvent's event handling capabilities, read no
further.
The second part focuses on network programming using sockets, for which
AnyEvent offers a lot of support you can use, and a lot of workarounds
around portability quirks.
=head1 What is AnyEvent?
If you don't care for the whys and want to see code, skip this section!
AnyEvent is first of all just a framework to do event-based
programming. Typically such frameworks are an all-or-nothing thing: If you
use one such framework, you can't (easily, or even at all) use another in
the same program.
AnyEvent is different - it is a thin abstraction layer on top of other
event loops, just like DBI is an abstraction of many different database
APIs. Its main purpose is to move the choice of the underlying framework
(the event loop) from the module author to the program author using the
module.
That means you can write code that uses events to control what it
does, without forcing other code in the same program to use the same
underlying framework as you do - i.e. you can create a Perl module
that is event-based using AnyEvent, and users of that module can still
choose between using L<Gtk2>, L<Tk>, L<Event> (or run inside Irssi or
rxvt-unicode) or any other supported event loop. AnyEvent even comes with
its own pure-perl event loop implementation, so your code works regardless
of other modules that might or might not be installed. The latter is
important, as AnyEvent does not have any hard dependencies to other
modules, which makes it easy to install, for example, when you lack a C
compiler. No matter what environment, AnyEvent will just cope with it.
A typical limitation of existing Perl modules such as L<Net::IRC> is that
they come with their own event loop: In L<Net::IRC>, a program which uses
it needs to start the event loop of L<Net::IRC>. That means that one
cannot integrate this module into a L<Gtk2> GUI for instance, as that
module, too, enforces the use of its own event loop (namely L<Glib>).
Another example is L<LWP>: it provides no event interface at all. It's
a pure blocking HTTP (and FTP etc.) client library, which usually means
that you either have to start another process or have to fork for a HTTP
request, or use threads (e.g. L<Coro::LWP>), if you want to do something
else while waiting for the request to finish.
The motivation behind these designs is often that a module doesn't want
to depend on some complicated XS-module (Net::IRC), or that it doesn't
want to force the user to use some specific event loop at all (LWP), out
of fear of severly limiting the usefulness of the module: If your module
requires Glib, it will not run in a Tk program.
L<AnyEvent> solves this dilemma, by B<not> forcing module authors to
either:
=over 4
=item - write their own event loop (because it guarantees the availability
of an event loop everywhere - even on windows with no extra modules
installed).
=item - choose one specific event loop (because AnyEvent works with most
event loops available for Perl).
=back
If the module author uses L<AnyEvent> for all his (or her) event needs
(IO events, timers, signals, ...) then all other modules can just use
his module and don't have to choose an event loop or adapt to his event
loop. The choice of the event loop is ultimately made by the program
author who uses all the modules and writes the main program. And even
there he doesn't have to choose, he can just let L<AnyEvent> choose the
most efficient event loop available on the system.
Read more about this in the main documentation of the L<AnyEvent> module.
=head1 Introduction to Event-Based Programming
So what exactly is programming using events? It quite simply means that
instead of your code actively waiting for something, such as the user
entering something on STDIN:
$| = 1; print "enter your name> ";
my $name = <STDIN>;
You instead tell your event framework to notify you in the event of some
data being available on STDIN, by using a callback mechanism:
use AnyEvent;
$| = 1; print "enter your name> ";
my $name;
my $wait_for_input = AnyEvent->io (
fh => \*STDIN, # which file handle to check
poll => "r", # which event to wait for ("r"ead data)
cb => sub { # what callback to execute
$name = <STDIN>; # read it
}
);
# do something else here
Looks more complicated, and surely is, but the advantage of using events
is that your program can do something else instead of waiting for input
(side note: combining AnyEvent with a thread package such as Coro can
recoup much of the simplicity, effectively getting the best of two
worlds).
Waiting as done in the first example is also called "blocking" the process
because you "block"/keep your process from executing anything else while
you do so.
The second example avoids blocking by only registering interest in a read
event, which is fast and doesn't block your process. The callback will
be called only when data is available and can be read without blocking.
The "interest" is represented by an object returned by C<< AnyEvent->io
>> called a "watcher" object - thus named because it "watches" your
file handle (or other event sources) for the event you are interested in.
In the example above, we create an I/O watcher by calling the C<<
AnyEvent->io >> method. A lack of further interest in some event is
expressed by simply forgetting about its watcher, for example by
C<undef>-ing the only variable it is stored in. AnyEvent will
automatically clean up the watcher if it is no longer used, much like
Perl closes your file handles if you no longer use them anywhere.
=head3 A short note on callbacks
A common issue that hits people is the problem of passing parameters
to callbacks. Programmers used to languages such as C or C++ are often
used to a style where one passes the address of a function (a function
reference) and some data value, e.g.:
sub callback {
my ($arg) = @_;
$arg->method;
}
my $arg = ...;
call_me_back_later \&callback, $arg;
This is clumsy, as the place where behaviour is specified (when the
callback is registered) is often far away from the place where behaviour
is implemented. It also doesn't use Perl syntax to invoke the code. There
is also an abstraction penalty to pay as one has to I<name> the callback,
which often is unnecessary and leads to nonsensical or duplicated names.
In Perl, one can specify behaviour much more directly by using
I<closures>. Closures are code blocks that take a reference to the
enclosing scope(s) when they are created. This means lexical variables
in scope when a closure is created can be used inside the closure:
my $arg = ...;
call_me_back_later sub { $arg->method };
Under most circumstances, closures are faster, use fewer resources and
result in much clearer code than the traditional approach. Faster,
because parameter passing and storing them in local variables in Perl
is relatively slow. Fewer resources, because closures take references
to existing variables without having to create new ones, and clearer
code because it is immediately obvious that the second example calls the
C<method> method when the callback is invoked.
Apart from these, the strongest argument for using closures with AnyEvent
is that AnyEvent does not allow passing parameters to the callback, so
closures are the only way to achieve that in most cases :->
=head3 A little hint to catch mistakes
AnyEvent does not check the parameters you pass in, at least not by
default. to enable checking, simply start your program with C<AE_STRICT=1>
in the environment, or put C<use AnyEvent::Strict> near the top of your
program:
AE_STRICT=1 perl myprogram
You can find more info on this and additional debugging aids later in this
introduction.
=head2 Condition Variables
Back to the I/O watcher example: The code is not yet a fully working
program, and will not work as-is. The reason is that your callback will
not be invoked out of the blue; you have to run the event loop first.
Also, event-based programs need to block sometimes too, such as when
there is nothing to do, and everything is waiting for new events to
arrive.
In AnyEvent, this is done using condition variables. Condition variables
are named "condition variables" because they represent a condition that is
initially false and needs to be fulfilled.
You can also call them "merge points", "sync points", "rendezvous ports"
or even callbacks and many other things (and they are often called these
names in other frameworks). The important point is that you can create them
freely and later wait for them to become true.
Condition variables have two sides - one side is the "producer" of the
condition (whatever code detects and flags the condition), the other side
is the "consumer" (the code that waits for that condition).
In our example in the previous section, the producer is the event callback
and there is no consumer yet - let's change that right now:
use AnyEvent;
$| = 1; print "enter your name> ";
my $name;
my $name_ready = AnyEvent->condvar;
my $wait_for_input = AnyEvent->io (
fh => \*STDIN,
poll => "r",
cb => sub {
$name = <STDIN>;
$name_ready->send;
}
);
# do something else here
# now wait until the name is available:
$name_ready->recv;
undef $wait_for_input; # watcher no longer needed
print "your name is $name\n";
This program creates an AnyEvent condvar by calling the C<<
AnyEvent->condvar >> method. It then creates a watcher as usual, but
inside the callback it C<send>s the C<$name_ready> condition variable,
which causes whoever is waiting on it to continue.
The "whoever" in this case is the code that follows, which calls C<<
$name_ready->recv >>: The producer calls C<send>, the consumer calls
C<recv>.
If there is no C<$name> available yet, then the call to C<<
$name_ready->recv >> will halt your program until the condition becomes
true.
As the names C<send> and C<recv> imply, you can actually send and receive
data using this, for example, the above code could also be written like
this, without an extra variable to store the name in:
use AnyEvent;
$| = 1; print "enter your name> ";
my $name_ready = AnyEvent->condvar;
my $wait_for_input = AnyEvent->io (
fh => \*STDIN, poll => "r",
cb => sub { $name_ready->send (scalar <STDIN>) }
);
# do something else here
# now wait and fetch the name
my $name = $name_ready->recv;
undef $wait_for_input; # watcher no longer needed
print "your name is $name\n";
You can pass any number of arguments to C<send>, and every subsequent
call to C<recv> will return them.
=head2 The "main loop"
Most event-based frameworks have something called a "main loop" or "event
loop run function" or something similar.
Just like in C<recv> AnyEvent, these functions need to be called
eventually so that your event loop has a chance of actually looking for
the events you are interested in.
For example, in a L<Gtk2> program, the above example could also be written
like this:
use Gtk2 -init;
use AnyEvent;
############################################
# create a window and some label
my $window = new Gtk2::Window "toplevel";
$window->add (my $label = new Gtk2::Label "soon replaced by name");
$window->show_all;
############################################
# do our AnyEvent stuff
$| = 1; print "enter your name> ";
my $wait_for_input = AnyEvent->io (
fh => \*STDIN, poll => "r",
cb => sub {
# set the label
$label->set_text (scalar <STDIN>);
print "enter another name> ";
}
);
############################################
# Now enter Gtk2's event loop
main Gtk2;
No condition variable anywhere in sight - instead, we just read a line
from STDIN and replace the text in the label. In fact, since nobody
C<undef>s C<$wait_for_input> you can enter multiple lines.
Instead of waiting for a condition variable, the program enters the Gtk2
main loop by calling C<< Gtk2->main >>, which will block the program and
wait for events to arrive.
This also shows that AnyEvent is quite flexible - you didn't have to do
anything to make the AnyEvent watcher use Gtk2 (actually Glib) - it just
worked.
Admittedly, the example is a bit silly - who would want to read names
from standard input in a Gtk+ application? But imagine that instead of
doing that, you make an HTTP request in the background and display its
results. In fact, with event-based programming you can make many
HTTP requests in parallel in your program and still provide feedback to
the user and stay interactive.
And in the next part you will see how to do just that - by implementing an
HTTP request, on our own, with the utility modules AnyEvent comes with.
Before that, however, let's briefly look at how you would write your
program using only AnyEvent, without ever calling some other event
loop's run function.
In the example using condition variables, we used those to start waiting
for events, and in fact, condition variables are the solution:
my $quit_program = AnyEvent->condvar;
# create AnyEvent watchers (or not) here
$quit_program->recv;
If any of your watcher callbacks decide to quit (this is often
called an "unloop" in other frameworks), they can just call C<<
$quit_program->send >>. Of course, they could also decide not to and
call C<exit> instead, or they could decide never to quit (e.g. in a
long-running daemon program).
If you don't need some clean quit functionality and just want to run the
event loop, you can do this:
AnyEvent->condvar->recv;
And this is, in fact, the closest to the idea of a main loop run
function that AnyEvent offers.
=head2 Timers and other event sources
So far, we have used only I/O watchers. These are useful mainly to find
out whether a socket has data to read, or space to write more data. On sane
operating systems this also works for console windows/terminals (typically
on standard input), serial lines, all sorts of other devices, basically
almost everything that has a file descriptor but isn't a file itself. (As
usual, "sane" excludes windows - on that platform you would need different
functions for all of these, complicating code immensely - think "socket
only" on windows).
However, I/O is not everything - the second most important event source is
the clock. For example when doing an HTTP request you might want to time
out when the server doesn't answer within some predefined amount of time.
In AnyEvent, timer event watchers are created by calling the C<<
AnyEvent->timer >> method:
use AnyEvent;
my $cv = AnyEvent->condvar;
my $wait_one_and_a_half_seconds = AnyEvent->timer (
after => 1.5, # after how many seconds to invoke the cb?
cb => sub { # the callback to invoke
$cv->send;
},
);
# can do something else here
# now wait till our time has come
$cv->recv;
Unlike I/O watchers, timers are only interested in the amount of seconds
they have to wait. When (at least) that amount of time has passed,
AnyEvent will invoke your callback.
Unlike I/O watchers, which will call your callback as many times as there
is data available, timers are normally one-shot: after they have "fired"
once and invoked your callback, they are dead and no longer do anything.
To get a repeating timer, such as a timer firing roughly once per second,
you can specify an C<interval> parameter:
my $once_per_second = AnyEvent->timer (
after => 0, # first invoke ASAP
interval => 1, # then invoke every second
lib/AnyEvent/Intro.pod view on Meta::CPAN
args: poll r fh GLOB(0x35283f0)
created: 2011-09-01 23:13:46.597336 +0200 (1314911626.59734)
file: ./blib/lib/Deliantra/Client/private/DC/DB.pm
line: 472
subname: DC::DB::Server::run
context:
tracing: enabled
cb: CODE(0x2d1fb98) (DC::DB::Server::fh_read)
invoked: 0 times
created
(eval 25) line 6 AnyEvent::Debug::Wrap::__ANON__('AnyEvent','fh',GLOB(0x35283f0),'poll','r','cb',CODE(0x2d1fb98)=DC::DB::Server::fh_read)
DC::DB line 472 AE::io(GLOB(0x35283f0),'0',CODE(0x2d1fb98)=DC::DB::Server::fh_read)
bin/deliantra line 2776 DC::DB::Server::run()
bin/deliantra line 2941 main::main()
There are many ways to get at this data - see the L<AnyEvent::Debug> and
L<AnyEvent::Log> manpages for more details.
The most interesting and interactive way is to create a debug shell, for
example by setting C<AE_DEBUG_SHELL>:
AE_DEBUG_WRAP=2 AE_DEBUG_SHELL=$HOME/myshell ./myprog
# while myprog is running:
socat readline $HOME/myshell
Note that anybody who can access F<$HOME/myshell> can make your program
do anything he or she wants, so if you are not the only user on your
machine, better put it into a secure location (F<$HOME> might not be
secure enough).
If you don't have C<socat> (a shame!) and care even less about security,
you can also use TCP and C<telnet>:
AE_DEBUG_WRAP=2 AE_DEBUG_SHELL=127.0.0.1:1234 ./myprog
telnet 127.0.0.1 1234
The debug shell can enable and disable tracing of watcher invocations,
can display the trace output, give you a list of watchers and lets you
investigate watchers in detail.
=back
This concludes our little tutorial.
=head1 Where to go from here?
This introduction should have explained the key concepts of L<AnyEvent>
- event watchers and condition variables, L<AnyEvent::Socket> - basic
networking utilities, and L<AnyEvent::Handle> - a nice wrapper around
sockets.
You could either start coding stuff right away, look at those manual
pages for the gory details, or roam CPAN for other AnyEvent modules (such
as L<AnyEvent::IRC> or L<AnyEvent::HTTP>) to see more code examples (or
simply to use them).
If you need a protocol that doesn't have an implementation using AnyEvent,
remember that you can mix AnyEvent with one other event framework, such as
L<POE>, so you can always use AnyEvent for your own tasks plus modules of
one other event framework to fill any gaps.
And last not least, you could also look at L<Coro>, especially
L<Coro::AnyEvent>, to see how you can turn event-based programming from
callback style back to the usual imperative style (also called "inversion
of control" - AnyEvent calls I<you>, but Coro lets I<you> call AnyEvent).
=head1 Authors
Robin Redeker C<< <elmex at ta-sa.org> >>, Marc Lehmann <schmorp@schmorp.de>.
( run in 1.023 second using v1.01-cache-2.11-cpan-df04353d9ac )