NAME
Proc::tored::Manager - OO interface to creating a proctored service
VERSION
version 0.06
SYNOPSIS
my $proctor = Proc::tored::Manager->new(dir => '/tmp', name => 'my-service');
# Call do_stuff while the service is running or until do_stuff returns false
$proctor->service(\&do_stuff)
or die sprintf('process %d is already running this service!', $proctor->running_pid);
# Signal another process running this service to quit gracefully, throwing an
# error if it does not self-terminate after 15 seconds.
if (my $pid = $proctor->stop_running_process(15)) {
die "process $pid is being stubborn!";
}
DESCRIPTION
Objective interface for creating and managing a proctored service.
METHODS
new
Creates a new service object, which can be used to run the service and/or signal another process to quit. The pid file is not created or accessed by this method.
- name
-
The file name to be used when creating or accessing the service's associated pid file.
- dir
-
A valid directory path where the pid file is to be created or an existing pid file is to be found.
- term_file
-
By default (and on supported platforms), posix signals are used to signal a managed process to voluntarily self-terminate. On non-compliant systems (e.g. MSWin32), a touch file is used instead. The path to this file is automatically constructed from "name" in "dir" unless manually specified.
- filepath
-
Unless manually specified, the pid file's
filepath
is constructed from "name" in "dir".
filepath
Returns the file system path created by concatenating the values of dir
and name
that were passed to new
.
is_running
See "is_running" in Proc::tored::Role::Running.
service
Accepts a code ref which will be called repeatedly until it or "is_running" return false.
Example using a pool of forked workers, an imaginary task queue, and a secondary condition that decides whether to stop running (aside from the built-in signal handlers):
$proctor->service(sub {
# Wait for an available worker, but with a timeout
my $worker = $worker_pool->next_available(0.1);
if ($worker) {
# Pull next task from the queue with a 0.1s timeout
my $task = poll_queue_with_timeout(0.1);
if ($task) {
$worker->assign($task);
}
}
return unless touch_file_exists();
return 1;
});
read_pid
Returns the pid identified in the pid file. Returns 0 if the pid file does not exist or is empty.
running_pid
Returns the pid of an already-running process or 0 if the pid file does not exist, is empty, or the process identified by the pid does not exist or is not visible.
stop_running_process
Signals a running instance to self-terminate. Returns 0 immediately if the pid file does not exist or is empty. Otherwise, polls the running process until the OS reports that it is no longer able to receive signals (with `kill(0, $pid)`).
Optional parameter $timeout
may be specified in fractional seconds, causing stop_running_process
to block up to (around) $timeout
seconds waiting for the signaled process to exit. Optional parameter $sleep
specifies the interval between polls in fractional seconds.
Returns the pid of the completed process otherwise.
$service->stop_running_process; # signal running process and return
$service->stop_running_process(10, 0.5); # signal, then poll every 0.5s for 10s
run_lock
Attempts to atomically acquire the run lock. Once held, the pid file is created (if needed) and the current process' pid is written to it, "is_running" will return true and a signal handlers will be active. Existing handlers will be executed after the one assigned for the run lock.
If the lock is acquired, a Guard object is returned that will release the lock once out of scope. Returns undef otherwise.
"service" is preferred to this method for most uses.
AUTHOR
Jeff Ober <jeffober@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2017 by Jeff Ober.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.