Perl Module for Multiprocessing
Process::SubProcess - Perl Module for Multiprocessing
Running Sub Processes in an easy way while reading STDOUT, STDERR, Exit Code and possible System Errors. \
It also implements running multiple Sub Processes simultaneously while keeping all Report and Error Messages and Exit Codes
seperate.
Some important Features are:
This Module was conceived out of the need to launch multiple Tasks simultaneously
while still keeping each Log and Error Messages and Exit Codes separately.\
As I developed it as Prototype at:\
Multi Process Manager\
The Object Oriented Design permits the implementation of the Command Pattern / Manager-Worker Pattern with the Process:
and :Group
Process:
Packages.\:Pool
Having a similar implementation as the Capture::Tiny
Package
it eventually evolved as a Procedural Replacement for the Capture:
Function:capture()
which is demonstrated under Usage > runSubProcess() Function.\
This capability also enabled its usage as Command Line Helper Tool with the run_subprocess.pl
script
as seen under Usage > Runner Script.
The Usefulness of this Library is best shown by an Example Use Case as seen in the Process:
Test Sequence:\:Run
Having 3 Jobs at hand of 2 seconds, 3 seconds and 1 second running them sequencially would take aproximately 6 seconds.\
But using the Process:
it takes effectively only 3 seconds to complete.\:Group
And still each Job can be evaluated separately by their own Results keeping Log Message separate from Error Messages and
viewing them in their context.
# Subtest: Process::SubProcess::Group::Run
ok 1 - scripts (count: '3'): added correctly
Process Group Execution Start - Time Now: '1688542787.31262' s
ok 2 - Process Group Execution: Execution correct
Process Group Execution End - Time Now: '1688542790.33528' s
Process Group Execution finished in '3022.66407012939' ms
ok 3 - Process No. '0': Listed correctly
Process (8608) 'test-script:2s':
ERROR CODE: '0'
EXIT CODE: '0'
STDOUT: 'Start - Time Now: '1688542787.33535' s
script 'test_script.pl' START 0
script 'test_script.pl' PAUSE '2' ...
script 'test_script.pl' END 1
End - Time Now: '1688542789.33552' s
script 'test_script.pl' done in '2000.16403198242' ms
script 'test_script.pl' EXIT '0'
'
STDERR: 'script 'test_script.pl' START 0 ERROR
script 'test_script.pl' END 1 ERROR
'
ok 4 - Process No. '1': Listed correctly
Process (8609) 'test-script:3s':
ERROR CODE: '0'
EXIT CODE: '0'
STDOUT: 'Start - Time Now: '1688542787.3336' s
script 'test_script.pl' START 0
script 'test_script.pl' PAUSE '3' ...
script 'test_script.pl' END 1
End - Time Now: '1688542790.3338' s
script 'test_script.pl' done in '3000.19979476929' ms
script 'test_script.pl' EXIT '0'
'
STDERR: 'script 'test_script.pl' START 0 ERROR
script 'test_script.pl' END 1 ERROR
'
ok 5 - Process No. '2': Listed correctly
Process (8610) 'test-script:1s':
ERROR CODE: '0'
EXIT CODE: '0'
STDOUT: 'Start - Time Now: '1688542787.34636' s
script 'test_script.pl' START 0
script 'test_script.pl' PAUSE '1' ...
script 'test_script.pl' END 1
End - Time Now: '1688542788.34656' s
script 'test_script.pl' done in '1000.20098686218' ms
script 'test_script.pl' EXIT '0'
'
STDERR: 'script 'test_script.pl' START 0 ERROR
script 'test_script.pl' END 1 ERROR
'
1..5
ok 3 - Process::SubProcess::Group::Run
The new Runner Script run_subprocess.pl
lets process the output of different commandline tools
in a organised manner and parse it correctly into JSON, YAML or Plain Text formats:
$ bin/run_subprocess.pl -n "test-script fails" -c "t/test_script.pl 2 6" -f json | jq '.'
{
"stdout": "Start - Time Now: '1688630328.73393' s\nscript 'test_script.pl' START 0\nscript 'test_script.pl' PAUSE '2' ...\nscript 'test_script.pl' END 1\nEnd - Time Now: '1688630330.73409' s\nscript 'test_script.pl' done in '2000.15306472778' ms\nscript 'test_script.pl' EXIT '6'\n",
"name": "test-script fails",
"error_code": 1,
"stderr": "script 'test_script.pl' START 0 ERROR\nscript 'test_script.pl' END 1 ERROR\n",
"exit_code": 6,
"command": "t/test_script.pl 2 6",
"pid": "7273"
}
$ bin/run_subprocess.pl -n "test-script fails" -c "t/test_script.pl 2 6" -f json | jq '.error_code,.exit_code'
1
6
$ bin/run_subprocess.pl -n "test-script fails" -c "t/test_script.pl 2 6" -f json | jq '.stderr,.exit_code,.error_code'
"script 'test_script.pl' START 0 ERROR\nscript 'test_script.pl' END 1 ERROR\n"
6
1
Demonstrating the runSubProcess()
Function Use Case:
use Process::SubProcess qw(runSubProcess);
use Test::More;
my $spath = '/path/to/test/script/';
my $stestscript = 'test_script.pl';
my $itestpause = 3;
my $iteststatus = 4;
my $rscriptlog = undef;
my $rscripterror = undef;
my $iscriptstatus = -1;
my $irunok = -1;
subtest 'runSubProcess() Function' => sub {
#Execute the Command
($rscriptlog, $rscripterror, $iscriptstatus)
= runSubProcess("${spath}${stestscript} $itestpause $iteststatus");
#Evaluate the Results
isnt($rscriptlog, undef, "STDOUT Ref is returned");
isnt($rscripterror, undef, "STDERR Ref is returned");
isnt($iscriptstatus, undef, "EXIT CODE is returned");
ok($iscriptstatus =~ qr/^-?\d$/, "EXIT CODE is numeric");
is($iscriptstatus, $iteststatus, 'EXIT CODE is correct');
print("EXIT CODE: '$iscriptstatus'\n");
if(defined $rscriptlog)
{
isnt($$rscriptlog, '', "STDOUT was captured");
print("STDOUT: '$$rscriptlog'\n");
} #if(defined $rscriptlog)
if(defined $rscripterror)
{
isnt($$rscripterror, '', "STDERR was captured");
print("STDERR: '$$rscripterror'\n");
} #if(defined $rscripterror)
};
done_testing();
The Class Diagramm kann be found at:\
Class Diagram for the Package ‘Process’\