1Mojo::IOLoop::ReadWriteUPsreorceCsosn(t3rpimb)uted PerlMDoojcou:m:eInOtLaotoipo:n:ReadWriteProcess(3pm)
2
3
4
6 Mojo::IOLoop::ReadWriteProcess - Execute external programs or internal
7 code blocks as separate process.
8
10 use Mojo::IOLoop::ReadWriteProcess;
11
12 # Code fork
13 my $process = Mojo::IOLoop::ReadWriteProcess->new(sub { print "Hello\n" });
14 $process->start();
15 print "Running\n" if $process->is_running();
16 $process->getline(); # Will return "Hello\n"
17 $process->pid(); # Process id
18 $process->stop();
19 $process->wait_stop(); # if you intend to wait its lifespan
20
21 # Methods can be chained, thus this is valid:
22 use Mojo::IOLoop::ReadWriteProcess qw(process);
23 my $output = process( sub { print "Hello\n" } )->start()->wait_stop->getline;
24
25 # Handles seamelessy also external processes:
26 my $process = process(execute=> '/path/to/bin' )->args([qw(foo bar baz)]);
27 $process->start();
28 my $line_output = $process->getline();
29 my $pid = $process->pid();
30 $process->stop();
31 my @errors = $process->error;
32
33 # Get process return value
34 $process = process( sub { return "256"; } )->start()->wait_stop;
35 # We need to stop it to retrieve the exit status
36 my $return = $process->return_status;
37
38 # We can access directly to handlers from the object:
39 my $stdout = $process->read_stream;
40 my $stdin = $process->write_stream;
41 my $stderr = $process->error_stream;
42
43 # So this works:
44 print $stdin "foo bar\n";
45 my @lines = <$stdout>;
46
47 # There is also an alternative channel of communication (just for forked processes):
48 my $channel_in = $process->channel_in; # write to the child process
49 my $channel_out = $process->channel_out; # read from the child process
50 $process->channel_write("PING"); # convenience function
51
53 Mojo::IOLoop::ReadWriteProcess is yet another process manager.
54
56 Mojo::IOLoop::ReadWriteProcess inherits all events from
57 Mojo::EventEmitter and can emit the following new ones.
58
59 start
60 $process->on(start => sub {
61 my ($process) = @_;
62 $process->is_running();
63 });
64
65 Emitted when the process starts.
66
67 stop
68 $process->on(stop => sub {
69 my ($process) = @_;
70 $process->restart();
71 });
72
73 Emitted when the process stops.
74
75 process_error
76 $process->on(process_error => sub {
77 my ($e) = @_;
78 my @errors = @{$e};
79 });
80
81 Emitted when the process produce errors.
82
83 process_stuck
84 $process->on(process_stuck => sub {
85 my ($self) = @_;
86 ...
87 });
88
89 Emitted when "blocking_stop" is set and all attempts for killing the
90 process in "max_kill_attempts" have been exhausted. The event is
91 emitted before attempting to kill it with SIGKILL and becoming
92 blocking.
93
94 SIG_CHLD
95 $process->on(SIG_CHLD => sub {
96 my ($self) = @_;
97 ...
98 });
99
100 Emitted when we receive SIG_CHLD.
101
102 SIG_TERM
103 $process->on(SIG_TERM => sub {
104 my ($self) = @_;
105 ...
106 });
107
108 Emitted when the child forked process receives SIG_TERM, before
109 exiting.
110
111 collected
112 $process->on(collected => sub {
113 my ($self) = @_;
114 ...
115 });
116
117 Emitted right after status collection.
118
119 collect_status
120 $process->on(collect_status => sub {
121 my ($self) = @_;
122 ...
123 });
124
125 Emitted when on child process waitpid. It is used internally to get
126 the child process status. Note: events attached to it are wiped when
127 process has been stopped.
128
130 Mojo::IOLoop::ReadWriteProcess inherits all attributes from
131 Mojo::EventEmitter and implements the following new ones.
132
133 execute
134 use Mojo::IOLoop::ReadWriteProcess;
135 my $process = Mojo::IOLoop::ReadWriteProcess->new(execute => "/usr/bin/perl");
136 $process->start();
137 $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
138 $process->stop();
139
140 "execute" should contain the external program that you wish to run.
141
142 code
143 use Mojo::IOLoop::ReadWriteProcess;
144 my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" } );
145 $process->start();
146 $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
147 $process->stop();
148
149 It represent the code you want to run in background.
150
151 You do not need to specify "code", it is implied if no arguments is
152 given.
153
154 my $process = Mojo::IOLoop::ReadWriteProcess->new(sub { print "Hello" });
155 $process->start();
156 $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
157 $process->stop();
158
159 args
160 use Mojo::IOLoop::ReadWriteProcess;
161 my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello ".$_[1] }, args => "User" );
162 $process->start();
163 $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
164 $process->stop();
165
166 # The process will print "Hello User"
167
168 Arguments pass to the external binary or the code block. Use arrayref
169 to pass many.
170
171 blocking_stop
172 use Mojo::IOLoop::ReadWriteProcess;
173 my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" }, blocking_stop => 1 );
174 $process->start();
175 $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
176 $process->stop(); # Will wait indefinitely until the process is stopped
177
178 Set it to 1 if you want to do blocking stop of the process.
179
180 channels
181 use Mojo::IOLoop::ReadWriteProcess;
182 my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" }, channels => 0 );
183 $process->start();
184 $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
185 $process->stop(); # Will wait indefinitely until the process is stopped
186
187 Set it to 0 if you want to disable internal channels.
188
189 session
190 use Mojo::IOLoop::ReadWriteProcess;
191 my $process = Mojo::IOLoop::ReadWriteProcess->new(sub { print "Hello" });
192 my $session = $process->session;
193 $session->enable_subreaper;
194
195 Returns the current Mojo::IOLoop::ReadWriteProcess::Session singleton.
196
197 subreaper
198 use Mojo::IOLoop::ReadWriteProcess;
199 my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello ".$_[1] }, args => "User" );
200 $process->subreaper(1)->start();
201 $process->on( stop => sub { shift()->disable_subreaper } );
202 $process->stop();
203
204 # The process will print "Hello User"
205
206 Mark the current process (not the child) as subreaper on start. It's
207 on invoker behalf to disable subreaper when process stops, as it marks
208 the current process and not the child.
209
210 ioloop
211 my $loop = $process->ioloop;
212 $subprocess = $process->ioloop(Mojo::IOLoop->new);
213
214 Event loop object to control, defaults to the global Mojo::IOLoop
215 singleton.
216
217 max_kill_attempts
218 use Mojo::IOLoop::ReadWriteProcess;
219 my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" }, max_kill_attempts => 50 );
220 $process->start();
221 $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
222 $process->stop(); # It will attempt to send SIGTERM 50 times.
223
224 Defaults to 5, is the number of attempts before bailing out.
225
226 It can be used with blocking_stop, so if the number of attempts are
227 exhausted, a SIGKILL and waitpid will be tried at the end.
228
229 kill_whole_group
230 use Mojo::IOLoop::ReadWriteProcess;
231 my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { setpgrp(0, 0); exec(...); }, kill_whole_group => 1 );
232 $process->start();
233 $process->send_signal(...); # Will skip the usual check whether $process->pid is running
234 $process->stop(); # Kills the entire process group and waits for all processes in the group to finish
235
236 Defaults to 0, whether to send signals (e.g. to stop) to the entire
237 process group.
238
239 This is useful when the sub process creates further sub processes and
240 creates a new process group as shown in the example. In this case it
241 might be useful to take care of the entire process group when stopping
242 and wait for every process in the group to finish.
243
244 collect_status
245 Defaults to 1, If enabled it will automatically collect the status of
246 the children process. Disable it in case you want to manage your
247 process child directly, and do not want to rely on automatic collect
248 status. If you won't overwrite your "SIGCHLD" handler, the "SIG_CHLD"
249 event will be still emitted.
250
251 serialize
252 Defaults to 0, If enabled data returned from forked process will be
253 serialized with Storable.
254
255 kill_sleeptime
256 Defaults to 1, it's the seconds to wait before attempting SIGKILL when
257 blocking_stop is set to 1.
258
259 separate_err
260 Defaults to 1, it will create a separate channel to intercept process
261 STDERR, otherwise it will be redirected to STDOUT.
262
263 verbose
264 Defaults to 1, it indicates message verbosity.
265
266 set_pipes
267 Defaults to 1, If enabled, additional pipes for process communication
268 are automatically set up.
269
270 internal_pipes
271 Defaults to 1, If enabled, additional pipes for retreiving process
272 return and errors are set up. Note: If you disable that, the only
273 information provided by the process will be the exit_status.
274
275 autoflush
276 Defaults to 1, If enabled autoflush of handlers is enabled
277 automatically.
278
279 error
280 Returns a Mojo::Collection of errors. Note: errors that can be
281 captured only at the end of the process
282
284 Mojo::IOLoop::ReadWriteProcess inherits all methods from
285 Mojo::EventEmitter and implements the following new ones.
286
287 start()
288 use Mojo::IOLoop::ReadWriteProcess qw(process);
289 my $p = process(sub {
290 print STDERR "Boo\n"
291 } )->start;
292
293 Starts the process
294
295 stop()
296 use Mojo::IOLoop::ReadWriteProcess qw(process);
297 my $p = process( execute => "/path/to/bin" )->start->stop;
298
299 Stop the process. Unless you use wait_stop(), it will attempt to kill
300 the process without waiting the process to finish. By defaults it send
301 "SIGTERM" to the child. You can change that by defining the internal
302 attribute "_default_kill_signal". Note, if you want to be *sure* that
303 the process gets killed, you can enable the "blocking_stop" attribute,
304 that will attempt to send "SIGKILL" after "max_kill_attempts" is
305 reached.
306
307 restart()
308 use Mojo::IOLoop::ReadWriteProcess qw(process);
309 my $p = process( execute => "/path/to/bin" )->restart;
310
311 It restarts the process if stopped, or if already running, it stops it
312 first.
313
314 is_running()
315 use Mojo::IOLoop::ReadWriteProcess qw(process);
316 my $p = process( execute => "/path/to/bin" )->start;
317 $p->is_running;
318
319 Boolean, it inspect if the process is currently running or not.
320
321 exit_status()
322 use Mojo::IOLoop::ReadWriteProcess qw(process);
323 my $p = process( execute => "/path/to/bin" )->start;
324
325 $p->wait_stop->exit_status;
326
327 Inspect the process exit status, it does the shifting magic, to access
328 to the real value call _status().
329
330 return_status()
331 use Mojo::IOLoop::ReadWriteProcess qw(process);
332 my $p = process( sub { return 42 } )->start;
333
334 my $s = $p->wait_stop->return_status; # 42
335
336 Inspect the codeblock return.
337
338 enable_subreaper()
339 use Mojo::IOLoop::ReadWriteProcess qw(process);
340 my $p = process()->enable_subreaper;
341
342 Mark the current process (not the child) as subreaper. This is used
343 typically if you want to mark further children as subreapers inside
344 other forks.
345
346 my $master_p = process(
347 sub {
348 my $p = shift;
349 $p->enable_subreaper;
350
351 process(sub { sleep 4; exit 1 })->start();
352 process(
353 sub {
354 sleep 4;
355 process(sub { sleep 1; })->start();
356 })->start();
357 process(sub { sleep 4; exit 0 })->start();
358 process(sub { sleep 4; die })->start();
359 my $manager
360 = process(sub { sleep 2 })->subreaper(1)->start();
361 sleep 1 for (0 .. 10);
362 $manager->stop;
363 return $manager->session->all->size;
364 });
365
366 $master_p->subreaper(1);
367
368 $master_p->on(collected => sub { $status++ });
369
370 # On start we setup the current process as subreaper
371 # So it's up on us to disable it after process is done.
372 $master_p->on(stop => sub { shift()->disable_subreaper });
373 $master_p->start();
374
375 disable_subreaper()
376 use Mojo::IOLoop::ReadWriteProcess qw(process);
377 my $p = process()->disable_subreaper;
378
379 Unset the current process (not the child) as subreaper.
380
381 prctl()
382 use Mojo::IOLoop::ReadWriteProcess qw(process);
383 my $p = process();
384 $p->prctl($option, $arg2, $arg3, $arg4, $arg5);
385
386 Internal function to execute and wrap the prctl syscall, accepts the
387 same arguments as prctl.
388
389 diag()
390 use Mojo::IOLoop::ReadWriteProcess qw(process);
391 my $p = process(sub { print "Hello\n" });
392 $p->on( stop => sub { shift->diag("Done!") } );
393 $p->start->wait_stop;
394
395 Internal function to print information to STDERR if verbose attribute
396 is set or either DEBUG mode enabled. You can use it if you wish to
397 display information on the process status.
398
399 to_ioloop()
400 use Mojo::IOLoop::ReadWriteProcess qw(process);
401
402 my $p = process(sub { print "Hello from first process\n"; sleep 1 });
403
404 $p->start(); # Start and sets the handlers
405 my $stream = $p->to_ioloop; # Get the stream and demand to IOLoop
406 my $output;
407
408 # Hook on Mojo::IOLoop::Stream events
409 $stream->on(read => sub { $output .= pop; $p->is_running ... });
410
411 Mojo::IOLoop->singleton->start() unless Mojo::IOLoop->singleton->is_running;
412
413 Returns a Mojo::IOLoop::Stream object and demand the wait operation to
414 Mojo::IOLoop. It needs "set_pipes" enabled. Default IOLoop can be
415 overridden in ioloop().
416
417 wait()
418 use Mojo::IOLoop::ReadWriteProcess qw(process);
419 my $p = process(sub { print "Hello\n" })->wait;
420 # ... here now you can mangle $p handlers and such
421
422 Waits until the process finishes, but does not performs cleanup
423 operations (until stop is called).
424
425 wait_stop()
426 use Mojo::IOLoop::ReadWriteProcess qw(process);
427 my $p = process(sub { print "Hello\n" })->start->wait_stop;
428 # $p is not running anymore, and all possible events have been granted to be emitted.
429
430 Waits until the process finishes, and perform cleanup operations.
431
432 errored()
433 use Mojo::IOLoop::ReadWriteProcess qw(process);
434 my $p = process(sub { die "Nooo" })->start->wait_stop;
435 $p->errored; # will return "1"
436
437 Returns a boolean indicating if the process had errors or not.
438
439 write_pidfile()
440 use Mojo::IOLoop::ReadWriteProcess qw(process);
441 my $p = process(sub { die "Nooo" } );
442 $p->pidfile("foobar");
443 $p->start();
444 $p->write_pidfile();
445
446 Forces writing PID of process to specified pidfile in the attributes of
447 the object. Useful only if the process have been already started,
448 otherwise if a pidfile it's supplied as attribute, it will be done
449 automatically.
450
451 write_stdin()
452 use Mojo::IOLoop::ReadWriteProcess qw(process);
453 my $p = process(sub { my $a = <STDIN>; print STDERR "Hello my name is $a\n"; } )->start;
454 $p->write_stdin("Larry");
455 $p->read_stderr; # process STDERR will contain: "Hello my name is Larry\n"
456
457 Write data to process STDIN.
458
459 write_channel()
460 use Mojo::IOLoop::ReadWriteProcess qw(process);
461 my $p = process(sub {
462 my $self = shift;
463 my $parent_output = $self->channel_out;
464 my $parent_input = $self->channel_in;
465
466 while(defined(my $line = <$parent_input>)) {
467 print $parent_output "PONG\n" if $line =~ /PING/i;
468 }
469 } )->start;
470 $p->write_channel("PING");
471 my $out = $p->read_channel;
472 # $out is PONG
473 my $child_output = $p->channel_out;
474 while(defined(my $line = <$child_output>)) {
475 print "Process is replying back with $line!\n";
476 $p->write_channel("PING");
477 }
478
479 Write data to process channel. Note, it's not STDIN, neither STDOUT,
480 it's a complete separate channel dedicated to parent-child
481 communication. In the parent process, you can access to the same pipes
482 (but from the opposite direction):
483
484 my $child_output = $self->channel_out;
485 my $child_input = $self->channel_in;
486
487 read_stdout()
488 use Mojo::IOLoop::ReadWriteProcess qw(process);
489 my $p = process(sub {
490 print "Boo\n"
491 } )->start;
492 $p->read_stdout;
493
494 Gets a single line from process STDOUT.
495
496 read_channel()
497 use Mojo::IOLoop::ReadWriteProcess qw(process);
498 my $p = process(sub {
499 my $self = shift;
500 my $parent_output = $self->channel_out;
501 my $parent_input = $self->channel_in;
502
503 print $parent_output "PONG\n";
504 } )->start;
505 $p->read_channel;
506
507 Gets a single line from process channel.
508
509 read_stderr()
510 use Mojo::IOLoop::ReadWriteProcess qw(process);
511 my $p = process(sub {
512 print STDERR "Boo\n"
513 } )->start;
514 $p->read_stderr;
515
516 Gets a single line from process STDERR.
517
518 read_all_stdout()
519 use Mojo::IOLoop::ReadWriteProcess qw(process);
520 my $p = process(sub {
521 print "Boo\n"
522 } )->start;
523 $p->read_all_stdout;
524
525 Gets all the STDOUT output of the process.
526
527 read_all_channel()
528 use Mojo::IOLoop::ReadWriteProcess qw(process);
529 my $p = process(sub {
530 shift->channel_out->write("Ping")
531 } )->start;
532 $p->read_all_channel;
533
534 Gets all the channel output of the process.
535
536 read_all_stderr()
537 use Mojo::IOLoop::ReadWriteProcess qw(process);
538 my $p = process(sub {
539 print STDERR "Boo\n"
540 } )->start;
541 $p->read_all_stderr;
542
543 Gets all the STDERR output of the process.
544
545 send_signal()
546 use Mojo::IOLoop::ReadWriteProcess qw(process);
547 use POSIX;
548 my $p = process( execute => "/path/to/bin" )->start;
549
550 $p->send_signal(POSIX::SIGKILL);
551
552 Send a signal to the process
553
555 parallel()
556 use Mojo::IOLoop::ReadWriteProcess qw(parallel);
557 my $pool = parallel sub { print "Hello\n" } => 5;
558 $pool->start();
559 $pool->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
560 $pool->stop();
561
562 Returns a Mojo::IOLoop::ReadWriteProcess::Pool object that represent a
563 group of processes.
564
565 It accepts the same arguments as Mojo::IOLoop::ReadWriteProcess, and
566 the last one represent the number of processes to generate.
567
568 batch()
569 use Mojo::IOLoop::ReadWriteProcess qw(batch);
570 my $pool = batch;
571 $pool->add(sub { print "Hello\n" });
572 $pool->on(stop => sub { shift->_diag("Done!") })->start->wait_stop;
573
574 Returns a Mojo::IOLoop::ReadWriteProcess::Pool object generated from
575 supplied arguments. It accepts as input the same parameter of
576 Mojo::IOLoop::ReadWriteProcess::Pool constructor ( see parallel() ).
577
578 process()
579 use Mojo::IOLoop::ReadWriteProcess qw(process);
580 my $p = process sub { print "Hello\n" };
581 $p->start()->wait_stop;
582
583 or even:
584
585 process(sub { print "Hello\n" })->start->wait_stop;
586
587 Returns a Mojo::IOLoop::ReadWriteProcess object that represent a
588 process.
589
590 It accepts the same arguments as Mojo::IOLoop::ReadWriteProcess.
591
592 queue()
593 use Mojo::IOLoop::ReadWriteProcess qw(queue);
594 my $q = queue;
595 $q->add(sub { return 42 } );
596 $q->consume;
597
598 Returns a Mojo::IOLoop::ReadWriteProcess::Queue object that represent a
599 queue.
600
602 You can set the MOJO_EVENTEMITTER_DEBUG environment variable to get
603 some advanced diagnostics information printed to STDERR.
604
605 MOJO_EVENTEMITTER_DEBUG=1
606
607 Also, you can set MOJO_PROCESS_DEBUG environment variable to get
608 diagnostics about the process execution.
609
610 MOJO_PROCESS_DEBUG=1
611
613 Copyright (C) Ettore Di Giacinto.
614
615 This library is free software; you can redistribute it and/or modify it
616 under the same terms as Perl itself.
617
619 Ettore Di Giacinto <edigiacinto@suse.com>
620
621
622
623perl v5.38.0 2023-09-24Mojo::IOLoop::ReadWriteProcess(3pm)