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

# Content
1 =head1 NAME
2
3 AnyEvent - provide framework for multiple event loops
4
5 Event, Coro, Glib, Tk - various supported event loops
6
7 =head1 SYNOPSIS
8
9 use AnyEvent;
10
11 my $w = AnyEvent->io (fh => ..., poll => "[rw]+", cb => sub {
12 my ($poll_got) = @_;
13 ...
14 });
15
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 ...
25 });
26
27 - 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
31 my $w = AnyEvent->condvar; # kind of main loop replacement
32 $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
40 =head1 DESCRIPTION
41
42 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 =over 4
58
59 =cut
60
61 package AnyEvent;
62
63 no warnings;
64 use strict 'vars';
65 use Carp;
66
67 our $VERSION = 0.3;
68 our $MODEL;
69
70 our $AUTOLOAD;
71 our @ISA;
72
73 my @models = (
74 [Coro => Coro::Event::],
75 [Event => Event::],
76 [Glib => Glib::],
77 [Tk => Tk::],
78 );
79
80 our %method = map +($_ => 1), qw(io timer condvar broadcast wait cancel DESTROY);
81
82 sub AUTOLOAD {
83 $AUTOLOAD =~ s/.*://;
84
85 $method{$AUTOLOAD}
86 or croak "$AUTOLOAD: not a valid method for AnyEvent objects";
87
88 unless ($MODEL) {
89 # check for already loaded models
90 for (@models) {
91 my ($model, $package) = @$_;
92 if (scalar keys %{ *{"$package\::"} }) {
93 eval "require AnyEvent::Impl::$model";
94 last if $MODEL;
95 }
96 }
97
98 unless ($MODEL) {
99 # try to load a model
100
101 for (@models) {
102 my ($model, $package) = @$_;
103 eval "require AnyEvent::Impl::$model";
104 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 }
110 }
111
112 @ISA = $MODEL;
113
114 my $class = shift;
115 $class->$AUTOLOAD (@_);
116 }
117
118 =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 =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 Then it creates a write-watcher which gets called whenever an error occurs
189 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 $txb->{cb}->($txn) of $txn->{cb}; # also call callback
216 }
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 return $txn->{result};
224
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 =head1 SEE ALSO
273
274 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
280 =head1
281
282 =cut
283
284 1
285