项目作者: bodo-hugo-barwich

项目描述 :
Perl Module for Multiprocessing
高级语言: Perl
项目地址: git://github.com/bodo-hugo-barwich/Process.git
创建时间: 2018-08-15T04:09:59Z
项目社区:https://github.com/bodo-hugo-barwich/Process

开源协议:

下载


Automated Tests
Publish new Release

Process

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.

Features

Some important Features are:

  • Asynchronous Launch
  • Reads Big Outputs
  • Execution Timeout
  • Configurable Read Interval
  • Captures possible System Errors at Launch Time like “file not found” Errors

Motivation

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::SubProcess::Group and Process::SubProcess::Pool Packages.\
Having a similar implementation as the Capture::Tiny Package
it eventually evolved as a Procedural Replacement for the Capture::Tiny::capture() Function
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.

Example Use Case

The Usefulness of this Library is best shown by an Example Use Case as seen in the Process::SubProcess::Group::Run Test Sequence:\
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::SubProcess::Group it takes effectively only 3 seconds to complete.\
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.

  1. # Subtest: Process::SubProcess::Group::Run
  2. ok 1 - scripts (count: '3'): added correctly
  3. Process Group Execution Start - Time Now: '1688542787.31262' s
  4. ok 2 - Process Group Execution: Execution correct
  5. Process Group Execution End - Time Now: '1688542790.33528' s
  6. Process Group Execution finished in '3022.66407012939' ms
  7. ok 3 - Process No. '0': Listed correctly
  8. Process (8608) 'test-script:2s':
  9. ERROR CODE: '0'
  10. EXIT CODE: '0'
  11. STDOUT: 'Start - Time Now: '1688542787.33535' s
  12. script 'test_script.pl' START 0
  13. script 'test_script.pl' PAUSE '2' ...
  14. script 'test_script.pl' END 1
  15. End - Time Now: '1688542789.33552' s
  16. script 'test_script.pl' done in '2000.16403198242' ms
  17. script 'test_script.pl' EXIT '0'
  18. '
  19. STDERR: 'script 'test_script.pl' START 0 ERROR
  20. script 'test_script.pl' END 1 ERROR
  21. '
  22. ok 4 - Process No. '1': Listed correctly
  23. Process (8609) 'test-script:3s':
  24. ERROR CODE: '0'
  25. EXIT CODE: '0'
  26. STDOUT: 'Start - Time Now: '1688542787.3336' s
  27. script 'test_script.pl' START 0
  28. script 'test_script.pl' PAUSE '3' ...
  29. script 'test_script.pl' END 1
  30. End - Time Now: '1688542790.3338' s
  31. script 'test_script.pl' done in '3000.19979476929' ms
  32. script 'test_script.pl' EXIT '0'
  33. '
  34. STDERR: 'script 'test_script.pl' START 0 ERROR
  35. script 'test_script.pl' END 1 ERROR
  36. '
  37. ok 5 - Process No. '2': Listed correctly
  38. Process (8610) 'test-script:1s':
  39. ERROR CODE: '0'
  40. EXIT CODE: '0'
  41. STDOUT: 'Start - Time Now: '1688542787.34636' s
  42. script 'test_script.pl' START 0
  43. script 'test_script.pl' PAUSE '1' ...
  44. script 'test_script.pl' END 1
  45. End - Time Now: '1688542788.34656' s
  46. script 'test_script.pl' done in '1000.20098686218' ms
  47. script 'test_script.pl' EXIT '0'
  48. '
  49. STDERR: 'script 'test_script.pl' START 0 ERROR
  50. script 'test_script.pl' END 1 ERROR
  51. '
  52. 1..5
  53. ok 3 - Process::SubProcess::Group::Run

Usage

Runner Script

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:

  1. $ bin/run_subprocess.pl -n "test-script fails" -c "t/test_script.pl 2 6" -f json | jq '.'
  2. {
  3. "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",
  4. "name": "test-script fails",
  5. "error_code": 1,
  6. "stderr": "script 'test_script.pl' START 0 ERROR\nscript 'test_script.pl' END 1 ERROR\n",
  7. "exit_code": 6,
  8. "command": "t/test_script.pl 2 6",
  9. "pid": "7273"
  10. }
  1. $ bin/run_subprocess.pl -n "test-script fails" -c "t/test_script.pl 2 6" -f json | jq '.error_code,.exit_code'
  2. 1
  3. 6
  1. $ bin/run_subprocess.pl -n "test-script fails" -c "t/test_script.pl 2 6" -f json | jq '.stderr,.exit_code,.error_code'
  2. "script 'test_script.pl' START 0 ERROR\nscript 'test_script.pl' END 1 ERROR\n"
  3. 6
  4. 1

runSubProcess() Function

Demonstrating the runSubProcess() Function Use Case:

  1. use Process::SubProcess qw(runSubProcess);
  2. use Test::More;
  3. my $spath = '/path/to/test/script/';
  4. my $stestscript = 'test_script.pl';
  5. my $itestpause = 3;
  6. my $iteststatus = 4;
  7. my $rscriptlog = undef;
  8. my $rscripterror = undef;
  9. my $iscriptstatus = -1;
  10. my $irunok = -1;
  11. subtest 'runSubProcess() Function' => sub {
  12. #Execute the Command
  13. ($rscriptlog, $rscripterror, $iscriptstatus)
  14. = runSubProcess("${spath}${stestscript} $itestpause $iteststatus");
  15. #Evaluate the Results
  16. isnt($rscriptlog, undef, "STDOUT Ref is returned");
  17. isnt($rscripterror, undef, "STDERR Ref is returned");
  18. isnt($iscriptstatus, undef, "EXIT CODE is returned");
  19. ok($iscriptstatus =~ qr/^-?\d$/, "EXIT CODE is numeric");
  20. is($iscriptstatus, $iteststatus, 'EXIT CODE is correct');
  21. print("EXIT CODE: '$iscriptstatus'\n");
  22. if(defined $rscriptlog)
  23. {
  24. isnt($$rscriptlog, '', "STDOUT was captured");
  25. print("STDOUT: '$$rscriptlog'\n");
  26. } #if(defined $rscriptlog)
  27. if(defined $rscripterror)
  28. {
  29. isnt($$rscripterror, '', "STDERR was captured");
  30. print("STDERR: '$$rscripterror'\n");
  31. } #if(defined $rscripterror)
  32. };
  33. done_testing();

Documentation

The Class Diagramm kann be found at:\
Class Diagram for the Package ‘Process’\
Class Diagram for the Package 'Process'