ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/README
Revision: 1.3
Committed: Sun Dec 4 09:44:32 2005 UTC (18 years, 5 months ago) by root
Branch: MAIN
CVS Tags: rel-0_3
Changes since 1.2: +147 -12 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
17 - AnyEvent will keep filehandles alive, so as long as the watcher
18 exists, the filehandle exists.
19
20 my $w = AnyEvent->timer (after => $seconds, cb => sub {
21 ...
22 });
23
24 - io and time watchers get canceled whenever $w is destroyed, so keep a
25 copy
26
27 - timers can only be used once and must be recreated for repeated
28 operation
29
30 my $w = AnyEvent->condvar; # kind of main loop replacement
31 $w->wait; # enters main loop till $condvar gets ->broadcast
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.
38
39 DESCRIPTION
40 AnyEvent provides an identical interface to multiple event loops. This
41 allows module authors to utilizy an event loop without forcing module
42 users to use the same event loop (as only a single event loop can
43 coexist peacefully at any one time).
44
45 The interface itself is vaguely similar but not identical to the Event
46 module.
47
48 On the first call of any method, the module tries to detect the
49 currently loaded event loop by probing wether any of the following
50 modules is loaded: Coro::Event, Event, Glib, Tk. The first one found is
51 used. If none is found, the module tries to load these modules in the
52 order given. The first one that could be successfully loaded will be
53 used. If still none could be found, it will issue an error.
54
55 EXAMPLE
56 The following program uses an io watcher to read data from stdin, a
57 timer to display a message once per second, and a condvar to exit the
58 program when the user enters quit:
59
60 use AnyEvent;
61
62 my $cv = AnyEvent->condvar;
63
64 my $io_watcher = AnyEvent->io (fh => \*STDIN, poll => 'r', cb => sub {
65 warn "io event <$_[0]>\n"; # will always output <r>
66 chomp (my $input = <STDIN>); # read a line
67 warn "read: $input\n"; # output what has been read
68 $cv->broadcast if $input =~ /^q/i; # quit program if /^q/i
69 });
70
71 my $time_watcher; # can only be used once
72
73 sub new_timer {
74 $timer = AnyEvent->timer (after => 1, cb => sub {
75 warn "timeout\n"; # print 'timeout' about every second
76 &new_timer; # and restart the time
77 });
78 }
79
80 new_timer; # create first timer
81
82 $cv->wait; # wait until user enters /^q/i
83
84 REAL-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
204 SEE ALSO
205 Event modules: Coro::Event, Coro, Event, Glib::Event, Glib.
206
207 Implementations: AnyEvent::Impl::Coro, AnyEvent::Impl::Event,
208 AnyEvent::Impl::Glib, AnyEvent::Impl::Tk.
209
210 Nontrivial usage example: Net::FCP.
211
212