1Mojo::IOLoop(3) User Contributed Perl Documentation Mojo::IOLoop(3)
2
3
4
6 Mojo::IOLoop - Minimalistic event loop
7
9 use Mojo::IOLoop;
10
11 # Listen on port 3000
12 Mojo::IOLoop->server({port => 3000} => sub {
13 my ($loop, $stream) = @_;
14
15 $stream->on(read => sub {
16 my ($stream, $bytes) = @_;
17
18 # Process input chunk
19 say $bytes;
20
21 # Write response
22 $stream->write('HTTP/1.1 200 OK');
23 });
24 });
25
26 # Connect to port 3000
27 my $id = Mojo::IOLoop->client({port => 3000} => sub {
28 my ($loop, $err, $stream) = @_;
29
30 $stream->on(read => sub {
31 my ($stream, $bytes) = @_;
32
33 # Process input
34 say "Input: $bytes";
35 });
36
37 # Write request
38 $stream->write("GET / HTTP/1.1\x0d\x0a\x0d\x0a");
39 });
40
41 # Add a timer
42 Mojo::IOLoop->timer(5 => sub {
43 my $loop = shift;
44 $loop->remove($id);
45 });
46
47 # Start event loop if necessary
48 Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
49
51 Mojo::IOLoop is a very minimalistic event loop based on Mojo::Reactor,
52 it has been reduced to the absolute minimal feature set required to
53 build solid and scalable non-blocking clients and servers.
54
55 Depending on operating system, the default per-process and system-wide
56 file descriptor limits are often very low and need to be tuned for
57 better scalability. The "LIBEV_FLAGS" environment variable should also
58 be used to select the best possible EV backend, which usually defaults
59 to the not very scalable "select".
60
61 LIBEV_FLAGS=1 # select
62 LIBEV_FLAGS=2 # poll
63 LIBEV_FLAGS=4 # epoll (Linux)
64 LIBEV_FLAGS=8 # kqueue (*BSD, OS X)
65
66 The event loop will be resilient to time jumps if a monotonic clock is
67 available through Time::HiRes. A TLS certificate and key are also built
68 right in, to make writing test servers as easy as possible. Also note
69 that for convenience the "PIPE" signal will be set to "IGNORE" when
70 Mojo::IOLoop is loaded.
71
72 For better scalability (epoll, kqueue) and to provide non-blocking name
73 resolution, SOCKS5 as well as TLS support, the optional modules EV
74 (4.0+), Net::DNS::Native (0.15+), IO::Socket::Socks (0.64+) and
75 IO::Socket::SSL (2.009+) will be used automatically if possible.
76 Individual features can also be disabled with the "MOJO_NO_NNR",
77 "MOJO_NO_SOCKS" and "MOJO_NO_TLS" environment variables.
78
79 See "REAL-TIME WEB" in Mojolicious::Guides::Cookbook for more.
80
82 Mojo::IOLoop inherits all events from Mojo::EventEmitter and can emit
83 the following new ones.
84
85 finish
86 $loop->on(finish => sub {
87 my $loop = shift;
88 ...
89 });
90
91 Emitted when the event loop wants to shut down gracefully and is just
92 waiting for all existing connections to be closed.
93
94 reset
95 $loop->on(reset => sub {
96 my $loop = shift;
97 ...
98 });
99
100 Emitted when the event loop is reset, this usually happens after the
101 process is forked to clean up resources that cannot be shared.
102
104 Mojo::IOLoop implements the following attributes.
105
106 max_accepts
107 my $max = $loop->max_accepts;
108 $loop = $loop->max_accepts(1000);
109
110 The maximum number of connections this event loop is allowed to accept,
111 before shutting down gracefully without interrupting existing
112 connections, defaults to 0. Setting the value to 0 will allow this
113 event loop to accept new connections indefinitely. Note that up to half
114 of this value can be subtracted randomly to improve load balancing
115 between multiple server processes, and to make sure that not all of
116 them restart at the same time.
117
118 max_connections
119 my $max = $loop->max_connections;
120 $loop = $loop->max_connections(100);
121
122 The maximum number of accepted connections this event loop is allowed
123 to handle concurrently, before stopping to accept new incoming
124 connections, defaults to 1000.
125
126 reactor
127 my $reactor = $loop->reactor;
128 $loop = $loop->reactor(Mojo::Reactor->new);
129
130 Low-level event reactor, usually a Mojo::Reactor::Poll or
131 Mojo::Reactor::EV object with a default subscriber to the event "error"
132 in Mojo::Reactor.
133
134 # Watch if handle becomes readable or writable
135 Mojo::IOLoop->singleton->reactor->io($handle => sub {
136 my ($reactor, $writable) = @_;
137 say $writable ? 'Handle is writable' : 'Handle is readable';
138 });
139
140 # Change to watching only if handle becomes writable
141 Mojo::IOLoop->singleton->reactor->watch($handle, 0, 1);
142
143 # Remove handle again
144 Mojo::IOLoop->singleton->reactor->remove($handle);
145
147 Mojo::IOLoop inherits all methods from Mojo::EventEmitter and
148 implements the following new ones.
149
150 acceptor
151 my $server = Mojo::IOLoop->acceptor($id);
152 my $server = $loop->acceptor($id);
153 my $id = $loop->acceptor(Mojo::IOLoop::Server->new);
154
155 Get Mojo::IOLoop::Server object for id or turn object into an acceptor.
156
157 client
158 my $id
159 = Mojo::IOLoop->client(address => '127.0.0.1', port => 3000, sub {...});
160 my $id = $loop->client(address => '127.0.0.1', port => 3000, sub {...});
161 my $id = $loop->client({address => '127.0.0.1', port => 3000} => sub {...});
162
163 Open a TCP/IP or UNIX domain socket connection with
164 Mojo::IOLoop::Client and create a stream object (usually
165 Mojo::IOLoop::Stream), takes the same arguments as "connect" in
166 Mojo::IOLoop::Client.
167
168 delay
169 my $delay = Mojo::IOLoop->delay;
170 my $delay = $loop->delay;
171 my $delay = $loop->delay(sub {...});
172 my $delay = $loop->delay(sub {...}, sub {...});
173
174 Build Mojo::IOLoop::Delay object to use as a promise and/or for flow-
175 control. Callbacks will be passed along to "steps" in
176 Mojo::IOLoop::Delay.
177
178 # Wrap continuation-passing style APIs with promises
179 my $ua = Mojo::UserAgent->new;
180 sub get {
181 my $promise = Mojo::IOLoop->delay;
182 $ua->get(@_ => sub {
183 my ($ua, $tx) = @_;
184 my $err = $tx->error;
185 if (!$err || $err->{code}) { $promise->resolve($tx) }
186 else { $promise->reject($err->{message}) }
187 });
188 return $promise;
189 }
190 my $mojo = get('https://mojolicious.org');
191 my $cpan = get('https://metacpan.org');
192 Mojo::Promise->race($mojo, $cpan)->then(sub { say shift->req->url })->wait;
193
194 # Synchronize multiple non-blocking operations
195 my $delay = Mojo::IOLoop->delay(sub { say 'BOOM!' });
196 for my $i (1 .. 10) {
197 my $end = $delay->begin;
198 Mojo::IOLoop->timer($i => sub {
199 say 10 - $i;
200 $end->();
201 });
202 }
203 $delay->wait;
204
205 # Sequentialize multiple non-blocking operations
206 Mojo::IOLoop->delay(
207
208 # First step (simple timer)
209 sub {
210 my $delay = shift;
211 Mojo::IOLoop->timer(2 => $delay->begin);
212 say 'Second step in 2 seconds.';
213 },
214
215 # Second step (concurrent timers)
216 sub {
217 my $delay = shift;
218 Mojo::IOLoop->timer(1 => $delay->begin);
219 Mojo::IOLoop->timer(3 => $delay->begin);
220 say 'Third step in 3 seconds.';
221 },
222
223 # Third step (the end)
224 sub { say 'And done after 5 seconds total.' }
225 )->wait;
226
227 is_running
228 my $bool = Mojo::IOLoop->is_running;
229 my $bool = $loop->is_running;
230
231 Check if event loop is running.
232
233 next_tick
234 my $undef = Mojo::IOLoop->next_tick(sub {...});
235 my $undef = $loop->next_tick(sub {...});
236
237 Execute callback as soon as possible, but not before returning or other
238 callbacks that have been registered with this method, always returns
239 "undef".
240
241 # Perform operation on next reactor tick
242 Mojo::IOLoop->next_tick(sub {
243 my $loop = shift;
244 ...
245 });
246
247 one_tick
248 Mojo::IOLoop->one_tick;
249 $loop->one_tick;
250
251 Run event loop until an event occurs.
252
253 # Don't block longer than 0.5 seconds
254 my $id = Mojo::IOLoop->timer(0.5 => sub {});
255 Mojo::IOLoop->one_tick;
256 Mojo::IOLoop->remove($id);
257
258 recurring
259 my $id = Mojo::IOLoop->recurring(3 => sub {...});
260 my $id = $loop->recurring(0 => sub {...});
261 my $id = $loop->recurring(0.25 => sub {...});
262
263 Create a new recurring timer, invoking the callback repeatedly after a
264 given amount of time in seconds.
265
266 # Perform operation every 5 seconds
267 Mojo::IOLoop->recurring(5 => sub {
268 my $loop = shift;
269 ...
270 });
271
272 remove
273 Mojo::IOLoop->remove($id);
274 $loop->remove($id);
275
276 Remove anything with an id, connections will be dropped gracefully by
277 allowing them to finish writing all data in their write buffers.
278
279 reset
280 Mojo::IOLoop->reset;
281 $loop->reset;
282
283 Remove everything and stop the event loop.
284
285 server
286 my $id = Mojo::IOLoop->server(port => 3000, sub {...});
287 my $id = $loop->server(port => 3000, sub {...});
288 my $id = $loop->server({port => 3000} => sub {...});
289
290 Accept TCP/IP and UNIX domain socket connections with
291 Mojo::IOLoop::Server and create stream objects (usually
292 Mojo::IOLoop::Stream, takes the same arguments as "listen" in
293 Mojo::IOLoop::Server.
294
295 # Listen on random port
296 my $id = Mojo::IOLoop->server({address => '127.0.0.1'} => sub {
297 my ($loop, $stream, $id) = @_;
298 ...
299 });
300 my $port = Mojo::IOLoop->acceptor($id)->port;
301
302 singleton
303 my $loop = Mojo::IOLoop->singleton;
304
305 The global Mojo::IOLoop singleton, used to access a single shared event
306 loop object from everywhere inside the process.
307
308 # Many methods also allow you to take shortcuts
309 Mojo::IOLoop->timer(2 => sub { Mojo::IOLoop->stop });
310 Mojo::IOLoop->start;
311
312 # Restart active timer
313 my $id = Mojo::IOLoop->timer(3 => sub { say 'Timeout!' });
314 Mojo::IOLoop->singleton->reactor->again($id);
315
316 # Turn file descriptor into handle and watch if it becomes readable
317 my $handle = IO::Handle->new_from_fd($fd, 'r');
318 Mojo::IOLoop->singleton->reactor->io($handle => sub {
319 my ($reactor, $writable) = @_;
320 say $writable ? 'Handle is writable' : 'Handle is readable';
321 })->watch($handle, 1, 0);
322
323 start
324 Mojo::IOLoop->start;
325 $loop->start;
326
327 Start the event loop, this will block until "stop" is called. Note that
328 some reactors stop automatically if there are no events being watched
329 anymore.
330
331 # Start event loop only if it is not running already
332 Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
333
334 stop
335 Mojo::IOLoop->stop;
336 $loop->stop;
337
338 Stop the event loop, this will not interrupt any existing connections
339 and the event loop can be restarted by running "start" again.
340
341 stop_gracefully
342 Mojo::IOLoop->stop_gracefully;
343 $loop->stop_gracefully;
344
345 Stop accepting new connections and wait for already accepted
346 connections to be closed, before stopping the event loop.
347
348 stream
349 my $stream = Mojo::IOLoop->stream($id);
350 my $stream = $loop->stream($id);
351 my $id = $loop->stream(Mojo::IOLoop::Stream->new);
352
353 Get Mojo::IOLoop::Stream object for id or turn object into a
354 connection.
355
356 # Increase inactivity timeout for connection to 300 seconds
357 Mojo::IOLoop->stream($id)->timeout(300);
358
359 subprocess
360 my $subprocess = Mojo::IOLoop->subprocess(sub {...}, sub {...});
361 my $subprocess = $loop->subprocess;
362 my $subprocess = $loop->subprocess(sub {...}, sub {...});
363
364 Build Mojo::IOLoop::Subprocess object to perform computationally
365 expensive operations in subprocesses, without blocking the event loop.
366 Callbacks will be passed along to "run" in Mojo::IOLoop::Subprocess.
367
368 # Operation that would block the event loop for 5 seconds
369 Mojo::IOLoop->subprocess(
370 sub {
371 my $subprocess = shift;
372 sleep 5;
373 return '♥', 'Mojolicious';
374 },
375 sub {
376 my ($subprocess, $err, @results) = @_;
377 say "Subprocess error: $err" and return if $err;
378 say "I $results[0] $results[1]!";
379 }
380 );
381
382 timer
383 my $id = Mojo::IOLoop->timer(3 => sub {...});
384 my $id = $loop->timer(0 => sub {...});
385 my $id = $loop->timer(0.25 => sub {...});
386
387 Create a new timer, invoking the callback after a given amount of time
388 in seconds.
389
390 # Perform operation in 5 seconds
391 Mojo::IOLoop->timer(5 => sub {
392 my $loop = shift;
393 ...
394 });
395
397 You can set the "MOJO_IOLOOP_DEBUG" environment variable to get some
398 advanced diagnostics information printed to "STDERR".
399
400 MOJO_IOLOOP_DEBUG=1
401
403 Mojolicious, Mojolicious::Guides, <https://mojolicious.org>.
404
405
406
407perl v5.30.1 2020-01-30 Mojo::IOLoop(3)