1Mojo::IOLoop::ReadWriteUPsreorceCsosn(t3rpimb)uted PerlMDoojcou:m:eInOtLaotoipo:n:ReadWriteProcess(3pm)
2
3
4

NAME

6       Mojo::IOLoop::ReadWriteProcess - Execute external programs or internal
7       code blocks as separate process.
8

SYNOPSIS

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

DESCRIPTION

53       Mojo::IOLoop::ReadWriteProcess is yet another process manager.
54

EVENTS

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

ATTRIBUTES

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

METHODS

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

EXPORTS

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

DEBUGGING

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

LICENSE

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

AUTHOR

619       Ettore Di Giacinto <edigiacinto@suse.com>
620
621
622
623perl v5.38.0                      2023-09-24Mojo::IOLoop::ReadWriteProcess(3pm)
Impressum