ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/README
Revision: 1.4
Committed: Fri Dec 30 01:28:31 2005 UTC (18 years, 4 months ago) by root
Branch: MAIN
CVS Tags: rel-0_4
Changes since 1.3: +23 -10 lines
Log Message:
*** empty log message ***

File Contents

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