The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Proc::tored::Manager - OO interface to creating a proctored service

VERSION

version 0.10

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_wait(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 name of the service. Services created with an identical "name" and "dir" will use the same pid file and share flags.

dir

A valid run directory (/var/run is a common choice). The path must be writable.

pid_file

Unless manually specified, the pid file's path is "dir"/"name".pid.

stop_file

Unless manually specified, the stop file's path is "dir"/"name".stopped.

pause_file

Unless manually specified, the pause file's path is "dir"/"name".paused.

trap_signals

An optional array of signals (suitable for use in %SIG) allowed to end the "service" loop. Unless specified, no signal handlers are installed.

METHODS

stop

start

is_stopped

Controls and inspects the "stopped" flag. While stopped, the "service" loop will refuse to run.

pause

resume

is_paused

Controls and inspects the "paused" flag. While paused, the "service" loop will continue to run but will not execute the code block passed in.

clear_flags

Clears both the "stopped" and "paused" flags.

is_running

Returns true if the current process is the active, running process.

service

Accepts a code ref which will be called repeatedly until it returns false or the "stopped" flag is set. If the "paused" flag is set, will continue to rune but will not execute the code block until the "paused" flag has been cleared.

Example using a pool of forked workers, an imaginary task queue, and a secondary condition that decides whether to stop running.

  $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_wait

Sets the "stopped" flag and blocks until the running_pid exits or the $timeout is reached.

  $service->stop_wait(30); # stop and block for up to 30 seconds

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.