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

NAME

App::Base::Daemon::Supervisor - supervise daemon process

SYNOPSIS

    package App::Base::Daemon::Foo;
    use Moose;
    with 'App::Base::Daemon::Supervisor';

    sub documentation { return 'foo'; }
    sub options { ... }
    sub supervised_process {
        my $self = shift;
        # the main daemon process
        while(1) {
            # check if supervisor is alive, exit otherwise
            $self->ping_supervisor;
            # do something
            ...
        }
    }
    sub supervised_shutdown {
        # this is called during shutdown
    }

DESCRIPTION

App::Base::Daemon::Supervisor allows to run code under supervision, it also provides support for zero downtime reloading. When you run Supervisor based daemon, the first process becomes a supervisor, it forks a child process which invokes supervised_process method that should contain the main daemon code. Supervisor and worker connected with a socketpair. If the worker exits for some reason, the supervisor detects it and starts a new worker after a small delay. Worker should periodically call ping_supervisor method, so it would be able to detect the case when supervisor has been killed and exit.

If module needs hot reloading feature, it should redefine can_do_hot_reload method to return true value. In this case supervisor process sets a handler for SIGUSR2 signal. When SIGUSR2 signal is received, supervisor starts a new copy of the script via fork/exec, so this new copy runs a new code. New supervisor starts a worker process and waits a signal that this new worker is ready to do its job. To send that signal worker should invoke ready_to_take_over method. Then the new supervisor receives that signal, it sends SIGQUIT to the old supervisor and waits for it to exit. After the old supervisor exited (normally new supervisor detects that because it can flock the pid file), the new supervisor sends signal to the worker, ready_to_take_over method in worker returns, and worker can start doing its job. If supervisor receives SIGUSR2 when it is already in the process of reloading, it ignores this signal. If supervisor didn't get SIGQUIT in 60 seconds after starting hot reloading process, it sends SIGKILL to the new supervisor and resumes normal work.

REQUIRED METHODS

Class consuming this role must implement the following methods:

supervised_process

The main daemon subroutine. Inside this subroutine you should periodically check that supervisor is still alive using ping_supervisor method. If supervisor exited, daemon should also exit.

supervised_shutdown

This subroutine is executed then daemon process is shutting down. Put cleanup code inside.

ATTRIBUTES

is_supervisor

returns true inside supervisor process and false inside supervised daemon

delay_before_respawn

how long supervisor should wait after child process exited before starting a new child. Default value is 5.

supervisor_pipe

File descriptor of the pipe to supervisor

METHODS

$self->ping_supervisor

Should only be called from supervised process. Checks if supervisor is alive and initiates shutdown if it is not.

$self->ready_to_take_over

Used to support hot reloading. If daemon support hot restart, supervised_process is called while the old daemon is still running. supervised_process should perform initialization, e.g. open listening sockets, and then call this method. Method will cause termination of old daemon and after return the new process may start serving clients.

$self->daemon_run

See App::Base::Daemon

$self->handle_shutdown

See App::Base::Daemon

DEMOLISH

LICENSE AND COPYRIGHT

Copyright (C) 2010-2014 Binary.com

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.