ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent.pm
Revision: 1.6
Committed: Mon Dec 19 17:03:29 2005 UTC (18 years, 6 months ago) by root
Branch: MAIN
Changes since 1.5: +3 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.2 AnyEvent - provide framework for multiple event loops
4    
5     Event, Coro, Glib, Tk - various supported event loops
6 root 1.1
7     =head1 SYNOPSIS
8    
9 root 1.2 use AnyEvent;
10    
11 root 1.5 my $w = AnyEvent->io (fh => ..., poll => "[rw]+", cb => sub {
12 root 1.2 my ($poll_got) = @_;
13     ...
14     });
15 root 1.5
16     - only one io watcher per $fh and $poll type is allowed
17     (i.e. on a socket you can have one r + one w or one rw
18     watcher, not any more.
19    
20     - AnyEvent will keep filehandles alive, so as long as the watcher exists,
21     the filehandle exists.
22    
23     my $w = AnyEvent->timer (after => $seconds, cb => sub {
24 root 1.2 ...
25     });
26    
27 root 1.5 - io and time watchers get canceled whenever $w is destroyed, so keep a copy
28    
29     - timers can only be used once and must be recreated for repeated operation
30 root 1.2
31     my $w = AnyEvent->condvar; # kind of main loop replacement
32 root 1.5 $w->wait; # enters main loop till $condvar gets ->broadcast
33     $w->broadcast; # wake up current and all future wait's
34    
35     - condvars are used to give blocking behaviour when neccessary. Create
36     a condvar for any "request" or "event" your module might create, C<<
37     ->broadcast >> it when the event happens and provide a function that calls
38     C<< ->wait >> for it. See the examples below.
39 root 1.2
40 root 1.1 =head1 DESCRIPTION
41    
42 root 1.2 L<AnyEvent> provides an identical interface to multiple event loops. This
43     allows module authors to utilizy an event loop without forcing module
44     users to use the same event loop (as only a single event loop can coexist
45     peacefully at any one time).
46    
47     The interface itself is vaguely similar but not identical to the Event
48     module.
49    
50     On the first call of any method, the module tries to detect the currently
51     loaded event loop by probing wether any of the following modules is
52     loaded: L<Coro::Event>, L<Event>, L<Glib>, L<Tk>. The first one found is
53     used. If none is found, the module tries to load these modules in the
54     order given. The first one that could be successfully loaded will be
55     used. If still none could be found, it will issue an error.
56    
57 root 1.1 =over 4
58    
59     =cut
60    
61     package AnyEvent;
62    
63 root 1.2 no warnings;
64     use strict 'vars';
65 root 1.1 use Carp;
66    
67 root 1.5 our $VERSION = 0.3;
68 root 1.2 our $MODEL;
69 root 1.1
70 root 1.2 our $AUTOLOAD;
71     our @ISA;
72 root 1.1
73     my @models = (
74     [Coro => Coro::Event::],
75     [Event => Event::],
76     [Glib => Glib::],
77     [Tk => Tk::],
78     );
79    
80 root 1.3 our %method = map +($_ => 1), qw(io timer condvar broadcast wait cancel DESTROY);
81    
82 root 1.1 sub AUTOLOAD {
83     $AUTOLOAD =~ s/.*://;
84    
85 root 1.3 $method{$AUTOLOAD}
86     or croak "$AUTOLOAD: not a valid method for AnyEvent objects";
87    
88 root 1.2 unless ($MODEL) {
89     # check for already loaded models
90     for (@models) {
91     my ($model, $package) = @$_;
92     if (scalar keys %{ *{"$package\::"} }) {
93 root 1.4 eval "require AnyEvent::Impl::$model";
94 root 1.2 last if $MODEL;
95     }
96 root 1.1 }
97    
98 root 1.2 unless ($MODEL) {
99     # try to load a model
100    
101     for (@models) {
102     my ($model, $package) = @$_;
103 root 1.4 eval "require AnyEvent::Impl::$model";
104 root 1.2 last if $MODEL;
105     }
106    
107     $MODEL
108     or die "No event module selected for AnyEvent and autodetect failed. Install any one of these modules: Coro, Event, Glib or Tk.";
109 root 1.1 }
110     }
111    
112 root 1.2 @ISA = $MODEL;
113    
114     my $class = shift;
115     $class->$AUTOLOAD (@_);
116 root 1.1 }
117    
118 root 1.2 =back
119    
120     =head1 EXAMPLE
121    
122     The following program uses an io watcher to read data from stdin, a timer
123     to display a message once per second, and a condvar to exit the program
124     when the user enters quit:
125    
126     use AnyEvent;
127    
128     my $cv = AnyEvent->condvar;
129    
130     my $io_watcher = AnyEvent->io (fh => \*STDIN, poll => 'r', cb => sub {
131     warn "io event <$_[0]>\n"; # will always output <r>
132     chomp (my $input = <STDIN>); # read a line
133     warn "read: $input\n"; # output what has been read
134     $cv->broadcast if $input =~ /^q/i; # quit program if /^q/i
135     });
136    
137     my $time_watcher; # can only be used once
138    
139     sub new_timer {
140     $timer = AnyEvent->timer (after => 1, cb => sub {
141     warn "timeout\n"; # print 'timeout' about every second
142     &new_timer; # and restart the time
143     });
144     }
145    
146     new_timer; # create first timer
147    
148     $cv->wait; # wait until user enters /^q/i
149    
150 root 1.5 =head1 REAL-WORLD EXAMPLE
151    
152     Consider the L<Net::FCP> module. It features (among others) the following
153     API calls, which are to freenet what HTTP GET requests are to http:
154    
155     my $data = $fcp->client_get ($url); # blocks
156    
157     my $transaction = $fcp->txn_client_get ($url); # does not block
158     $transaction->cb ( sub { ... } ); # set optional result callback
159     my $data = $transaction->result; # possibly blocks
160    
161     The C<client_get> method works like C<LWP::Simple::get>: it requests the
162     given URL and waits till the data has arrived. It is defined to be:
163    
164     sub client_get { $_[0]->txn_client_get ($_[1])->result }
165    
166     And in fact is automatically generated. This is the blocking API of
167     L<Net::FCP>, and it works as simple as in any other, similar, module.
168    
169     More complicated is C<txn_client_get>: It only creates a transaction
170     (completion, result, ...) object and initiates the transaction.
171    
172     my $txn = bless { }, Net::FCP::Txn::;
173    
174     It also creates a condition variable that is used to signal the completion
175     of the request:
176    
177     $txn->{finished} = AnyAvent->condvar;
178    
179     It then creates a socket in non-blocking mode.
180    
181     socket $txn->{fh}, ...;
182     fcntl $txn->{fh}, F_SETFL, O_NONBLOCK;
183     connect $txn->{fh}, ...
184     and !$!{EWOULDBLOCK}
185     and !$!{EINPROGRESS}
186     and Carp::croak "unable to connect: $!\n";
187    
188 root 1.6 Then it creates a write-watcher which gets called whenever an error occurs
189 root 1.5 or the connection succeeds:
190    
191     $txn->{w} = AnyEvent->io (fh => $txn->{fh}, poll => 'w', cb => sub { $txn->fh_ready_w });
192    
193     And returns this transaction object. The C<fh_ready_w> callback gets
194     called as soon as the event loop detects that the socket is ready for
195     writing.
196    
197     The C<fh_ready_w> method makes the socket blocking again, writes the
198     request data and replaces the watcher by a read watcher (waiting for reply
199     data). The actual code is more complicated, but that doesn't matter for
200     this example:
201    
202     fcntl $txn->{fh}, F_SETFL, 0;
203     syswrite $txn->{fh}, $txn->{request}
204     or die "connection or write error";
205     $txn->{w} = AnyEvent->io (fh => $txn->{fh}, poll => 'r', cb => sub { $txn->fh_ready_r });
206    
207     Again, C<fh_ready_r> waits till all data has arrived, and then stores the
208     result and signals any possible waiters that the request ahs finished:
209    
210     sysread $txn->{fh}, $txn->{buf}, length $txn->{$buf};
211    
212     if (end-of-file or data complete) {
213     $txn->{result} = $txn->{buf};
214     $txn->{finished}->broadcast;
215 root 1.6 $txb->{cb}->($txn) of $txn->{cb}; # also call callback
216 root 1.5 }
217    
218     The C<result> method, finally, just waits for the finished signal (if the
219     request was already finished, it doesn't wait, of course, and returns the
220     data:
221    
222     $txn->{finished}->wait;
223 root 1.6 return $txn->{result};
224 root 1.5
225     The actual code goes further and collects all errors (C<die>s, exceptions)
226     that occured during request processing. The C<result> method detects
227     wether an exception as thrown (it is stored inside the $txn object)
228     and just throws the exception, which means connection errors and other
229     problems get reported tot he code that tries to use the result, not in a
230     random callback.
231    
232     All of this enables the following usage styles:
233    
234     1. Blocking:
235    
236     my $data = $fcp->client_get ($url);
237    
238     2. Blocking, but parallelizing:
239    
240     my @datas = map $_->result,
241     map $fcp->txn_client_get ($_),
242     @urls;
243    
244     Both blocking examples work without the module user having to know
245     anything about events.
246    
247     3a. Event-based in a main program, using any support Event module:
248    
249     use Event;
250    
251     $fcp->txn_client_get ($url)->cb (sub {
252     my $txn = shift;
253     my $data = $txn->result;
254     ...
255     });
256    
257     Event::loop;
258    
259     3b. The module user could use AnyEvent, too:
260    
261     use AnyEvent;
262    
263     my $quit = AnyEvent->condvar;
264    
265     $fcp->txn_client_get ($url)->cb (sub {
266     ...
267     $quit->broadcast;
268     });
269    
270     $quit->wait;
271    
272 root 1.2 =head1 SEE ALSO
273    
274 root 1.5 Event modules: L<Coro::Event>, L<Coro>, L<Event>, L<Glib::Event>, L<Glib>.
275    
276     Implementations: L<AnyEvent::Impl::Coro>, L<AnyEvent::Impl::Event>, L<AnyEvent::Impl::Glib>, L<AnyEvent::Impl::Tk>.
277    
278     Nontrivial usage example: L<Net::FCP>.
279 root 1.2
280     =head1
281    
282     =cut
283    
284     1
285 root 1.1