NAME
Proc::PersistentControl - Start and Control Background Processes ("jobs", process groups)
SYNOPSIS
use Proc::PersistentControl;
my $controller = Proc::PersistentControl->new();
my $Proc =
$controller->StartProc({ [ timeout => 42, psynctime => 5,
Key => 'Value', ... ] },
"runme args");
my @Procs = $controller->ProcList(['Key', 'Value']);
my @Procs = $controller->RipeList();
my $alive = $Proc->IsAlive();
my $ripe = $Proc->IsRipe();
my $info = $Proc->Info();
my $info = $Proc->Reap();
$Proc->Kill();
DESCRIPTION
WARNING: This module (and its pod) is beta.
The method that is used by this module is calling for race conditions all over the place... Since version 1.0 most of these should be found. But there will still be bugs.
This module creates background processes and allows to track them from multiple invocations of a perl program, i. e. not only from the parent.
This is done in quite a KISS way: Information about background processes is stored in one directory per started process.
Special care is taken so that killing processes will also kill all child processes (i. e. grandchildren).
A timeout for the processes can be specified.
This module works on Unix and Windows. On Windows, Win32, Win32::Process and Win32::Job is required.
This module is intended to be as simple as possible. It should have as few other modules as prerequisites as possible, only modules that are likely to be installed in a "typical" perl installation (i. e. core modules, or "standard" Win32 modules on Windows). It should be usable on any Unix with the perl that comes with the OS.
The intended typical use cases of this module are things like programs that need to start and control "a few" background processes (something like max. 10 per minute or so), but consistently over multiple invocations of the program (like when they are scheduled by cron). Probably not a busy web server that needs to start hundreds of CGI processes per second.
The Controller Object, Process objects, and their Methods
Methods for the controller object
- Proc::PersistentControl->new([directory => $dir]);
-
Creates a controller object using $dir as place to store the persistent process information. If 'directory' is not specified, a directory called "ProcPersCtrl" will be created in "/var/tmp/$>" (Unix with /var/tmp), or in File::Spec->tmpdir() . "/$>" (Unix without /var/tmp), or in File::Spec->tmpdir() (Windows). (Note that tmpdir() is not tempdir(), i. e. the directory will always be the same. For certain values of 'always'.)
Note that preferring /var/tmp over tmpdir() allows information to survive a reboot on systems where /tmp is a tmpfs or similar. (This does not mean that your jobs will survive a reboot (they won't), and also the controller information might be corrupt if a reboot (or crash, or kill -9) kills your processes the hard way).
- $controller->StartProc({ [ timeout => 42, BLA => 'bla', ... ] }, "runme args");
- $controller->StartProc({ [ timeout => 42, BLA => 'bla', ... ] }, "runme", "arg1", "arg2", ...);
-
Start the program "runme" with command line arguments, optionally specifying a timeout after which the program will be killed. Other key-value pairs in the options are user defined only and can be retrieved via the Info() and Reap() methods, and be used to find processes by key-value pairs with the ProcList() method. Keys must not start with underscore, these are used internally (but will also be returned by Info() etc).
The program can be a "binary/excutable" that is in the $PATH (%PATH%), or a "script". Just try. Unix magic "#!" will also work under Windows (and even more...).
This method returns an object of class Proc::PersistentControl::Proc which has the methods described further below.
Since the internal information of the controller is stored in the filesystem, you can just terminate your program that uses the controller, start a new one later (giving the same directory to new()) and use all the methods described below. (But see Reap(), which destroys information).
- $controller->ProcList(['Key', 'Value'])
-
Returns a list of Proc::PersistentControl::Proc objects that are under control of the controller object. If a Key-Value pair is given, only processes with this Key-Value pair in their options are returned (see StartProc()).
- $controller->RipeList()
-
Returns a list of Proc::PersistentControl::Proc objects that are under control of the controller object and have terminated, i. e. are ready for reaping.
Methods for process objects
- $Proc->IsAlive()
-
Returns true if $Proc is still running.
- $Proc->IsRipe()
-
equivalent to "not $Proc->IsAlive()"
- $Proc->Info()
-
Returns a reference to hash that contains information about a process.
Usage:
sub type { print "$_[0]:\n"; open(T, $_[0]); print while (<T>); close(T); } sub printInfo { my $r = shift; foreach my $k (keys(%$r)) { my $v = $r->{$k}; print "$k=$v\n"; } type($r->{_dir} . '/STDOUT'); type($r->{_dir} . '/STDERR'); } printInfo($Proc->Info()); - $Proc->Reap()
-
Returns the process object's "Info()" information if $Proc->IsRipe().
The reaped information will be DESTROY'd after the process object goes out of scope. So make sure you use/copy the information before that. (Reap it and eat it before it gets bad).
- $Proc->Kill()
-
Kills the operating system process(es) that belong to $Proc. Should also kill grandchildren.
BUGS
The "make test" tests could be more detailed (but check out the examples, too.)
If you use controller objects with the same directory in parallel, be aware that Reap() will reap anything it can. If two calls to Reap() for the same process intersect, the result is unpredictable. So just don't do that, call Reap() only in one of the programs. Other behaviour when using one directory with more than one controller at the same time is considered to be a feature.
Using this module might interfere with your code if it also installs signal handlers, wait()s, etc. So don't do that.
The method to store information about the processes should use a more structured data format (like Persistent::File or so, but no more pre-reqs should be added).
Examples
Examples should be available in the Proc/PersistentControl/example directory (depending on your installation).
AUTHOR
Michael Staats, <michael.staats@gmx.eu>
COPYRIGHT AND LICENSE
Copyright (C) 2014 by Michael Staats
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.14.2 or, at your option, any later version of Perl 5 you may have available.