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

Comparing AnyEvent/README (file contents):
Revision 1.2 by root, Thu Dec 1 21:19:58 2005 UTC vs.
Revision 1.3 by root, Sun Dec 4 09:44:32 2005 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines