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