ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent.pm
Revision: 1.5
Committed: Sun Dec 4 09:44:32 2005 UTC (18 years, 7 months ago) by root
Branch: MAIN
CVS Tags: rel-0_3
Changes since 1.4: +147 -16 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     Then it creates a write-watcher which gets called wehnever 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     }
216    
217     The C<result> method, finally, just waits for the finished signal (if the
218     request was already finished, it doesn't wait, of course, and returns the
219     data:
220    
221     $txn->{finished}->wait;
222     return $txn->{buf};
223    
224     The actual code goes further and collects all errors (C<die>s, exceptions)
225     that occured during request processing. The C<result> method detects
226     wether an exception as thrown (it is stored inside the $txn object)
227     and just throws the exception, which means connection errors and other
228     problems get reported tot he code that tries to use the result, not in a
229     random callback.
230    
231     All of this enables the following usage styles:
232    
233     1. Blocking:
234    
235     my $data = $fcp->client_get ($url);
236    
237     2. Blocking, but parallelizing:
238    
239     my @datas = map $_->result,
240     map $fcp->txn_client_get ($_),
241     @urls;
242    
243     Both blocking examples work without the module user having to know
244     anything about events.
245    
246     3a. Event-based in a main program, using any support Event module:
247    
248     use Event;
249    
250     $fcp->txn_client_get ($url)->cb (sub {
251     my $txn = shift;
252     my $data = $txn->result;
253     ...
254     });
255    
256     Event::loop;
257    
258     3b. The module user could use AnyEvent, too:
259    
260     use AnyEvent;
261    
262     my $quit = AnyEvent->condvar;
263    
264     $fcp->txn_client_get ($url)->cb (sub {
265     ...
266     $quit->broadcast;
267     });
268    
269     $quit->wait;
270    
271 root 1.2 =head1 SEE ALSO
272    
273 root 1.5 Event modules: L<Coro::Event>, L<Coro>, L<Event>, L<Glib::Event>, L<Glib>.
274    
275     Implementations: L<AnyEvent::Impl::Coro>, L<AnyEvent::Impl::Event>, L<AnyEvent::Impl::Glib>, L<AnyEvent::Impl::Tk>.
276    
277     Nontrivial usage example: L<Net::FCP>.
278 root 1.2
279     =head1
280    
281     =cut
282    
283     1
284 root 1.1