ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent.pm (file contents):
Revision 1.3 by root, Thu Dec 1 21:19:58 2005 UTC vs.
Revision 1.7 by root, Fri Dec 30 01:28:31 2005 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines