MooseX::Control - Simple class to manage a execute deamon


MooseX-Control documentation Contained in the MooseX-Control distribution.

Index


Code Index:

NAME

Top

MooseX::Control - Simple class to manage a execute deamon

SYNOPSIS

Top

    package XXXX::Control;

    use Moose;
    with 'MooseX::Control';

    has '+control_name' => ( default => 'xxxx' );

    sub pre_startup   { inner() }
    sub post_startup  { inner() }
    sub pre_shutdown  { inner() }
    sub post_shutdown { inner() }

    sub get_server_pid { }
    sub construct_command_line { }
    sub find_pid_file { }

DESCRIPTION

Top

It is a Moose Role to ease writing XXX::Control like Sphinx::Control, Perlbal::Control

Please view source code for more details.

http://search.cpan.org/dist/Sphinx-Control/lib/Sphinx/Control.pm

http://search.cpan.org/dist/Perlbal-Control/lib/Perlbal/Control.pm

REQUIRED ATTRIBUTES AND METHODS

Top

ATTRIUTES

control_name

    has '+control_name' => ( default => 'perlbal' );
    # or
    has '+control_name' => ( default => 'searchd' );

METHODS

find_pid_file

To find a pid file for control_name

if the pid file is optional for control_name like perlbal, we return

    Path::Class::File->new('/tmp/unknown.pid')

construct_command_line

system command for start.

    sub construct_command_line {
        my $self = shift;

        my $conf = $self->config_file;
        (-f $conf)
            || confess "Could not locate configuration file ($conf)";

        ($self->binary_path, '--daemon', '--config', $conf->stringify);
    }

get_server_pid

a pid number for contorl_name

if $self->pid_file is there, we general write like:

    sub get_server_pid {
        my $self = shift;

        my $pid  = $self->pid_file->slurp(chomp => 1);
        ($pid)
            || confess "No PID found in pid_file (" . $self->pid_file . ")";
        $pid;
    }

if no $pid_file, we may use Proc::ProcessTable.

   sub get_server_pid {
        my $self = shift;

        my $pid_file     = $self->pid_file;

        if ( $pid_file ) {
            my $pid  = $pid_file->slurp(chomp => 1);
            ($pid)
                || confess "No PID found in pid_file (" . $pid_file . ")";
            return $pid;
        } else {
            my $config_file  = $self->config_file->stringify;
            my $control_name = $self->control_name;
            my $p = new Proc::ProcessTable( 'cache_ttys' => 1 );
            my $all = $p->table;
            foreach my $one (@$all) {
                if ($one->cmndline =~ /$control_name/ and $one->cmndline =~ /$config_file/) {
                    return $one->pid;
                }
            }
        }
        return 0;
    }

PROVIDED ATTRIBUTES AND METHODS

Top

ATTRIBUTES

binary_path

return a Path::Class::File of execute file like /usr/bin/search or /usr/bin/perlbal

verbose

controls $self->debug

METHODS

is_server_running

Checks to see if the control_name deamon that is currently being controlled by this instance is running or not (based on the state of the PID).

start

Starts the control_name deamon that is currently being controlled by this instance. It will also run the pre_startup and post_startup hooks.

stop

Stops the control_name deamon that is currently being controlled by this instance. It will also run the pre_shutdown and post_shutdown hooks.

SEE ALSO

Top

Moose, MooseX::Types::Path::Class, Sphinx::Control, Perlbal::Control

AUTHOR

Top

Fayland Lam, <fayland at gmail.com>

COPYRIGHT & LICENSE

Top


MooseX-Control documentation Contained in the MooseX-Control distribution.

package MooseX::Control;

use Moose::Role;
use Moose::Util::TypeConstraints;
use MooseX::Types::Path::Class;
use Path::Class;

our $VERSION   = '0.03';
our $AUTHORITY = 'cpan:FAYLAND';

has 'control_name' => (
    is   => 'rw',
    isa  => 'Str',
    default => 'unkown',
);

has 'config_file' => (
    is       => 'rw',
    isa      => 'Path::Class::File',
    coerce   => 1,
);

has 'binary_path' => (
    is      => 'rw',
    isa     => 'Path::Class::File',
    coerce  => 1,
    lazy    => 1,
    builder => '_find_binary_path'
);

sub _find_binary_path {
    my $self = shift;

    my $control_name = $self->control_name;
    my $control_exe = do {
        my $bin = `which $control_name`;
        chomp($bin);
        Path::Class::File->new($bin)
    };

    return $control_exe if -x $control_exe;

    for my $prefix (qw(/usr /usr/local /opt/local /sw)) {
        for my $bindir (qw(bin sbin)) {
            my $control_exe = Path::Class::File->new($prefix, $bindir, $control_name);
            return $control_exe if -x $control_exe;
        }
    }

    confess "can't find $control_name anywhere tried => (" . ($control_exe || 'nothing') . ")";
}

has 'pid_file' => (
    is      => 'rw',
    isa     => 'Path::Class::File',
    coerce  => 1,
    lazy    => 1,
    builder => 'find_pid_file',
);
requires 'find_pid_file';

my $sub_verbose = sub {
    my $msg = shift;
    $msg =~ s/\s+$//;
    print STDERR "$msg\n";
};
subtype 'Verbose'
    => as 'CodeRef'
    => where { 1; };
coerce 'Verbose'
    => from 'Int'
    => via {
        if ($_) {
            return $sub_verbose;
        } else {
            return sub { 0 };
        }
    };

has 'verbose' => ( is => 'rw', isa => 'Verbose', coerce => 1, default => 0 );

sub debug {
    my $self = shift;
    
    return unless $self->verbose;
    $self->verbose->(@_);
}

requires 'pre_startup';
requires 'pre_shutdown';
requires 'post_startup';
requires 'post_shutdown';

requires 'get_server_pid';
requires 'construct_command_line';

sub is_server_running {
    my $self = shift;
    
    my $pid_file = $self->pid_file;
    
    # no pid file, no server running ...
    if ($pid_file and $pid_file ne Path::Class::File->new('/tmp/unknown.pid')) {
        return 0 if (not -s $self->pid_file);
    }

    my $server_pid = $self->get_server_pid;
    return 0 if ( $server_pid == 0 );

    # check it ...
    kill(0, $server_pid) ? 1 : 0;
}

sub start {
    my $self = shift;
    
    my $control_name = $self->control_name;

    $self->debug("Starting $control_name ...");
    $self->pre_startup;

    # NOTE:
    # do this after startup so that it
    # would be possible to write the 
    # config file in the pre_startup
    # hook if we wanted to.
    # - SL
    my @cli = $self->construct_command_line;

    unless (system(@cli) == 0) {
        $self->debug("Could not start $control_name (@cli) exited with status $?");
        return;
    }

    $self->post_startup;

    $self->debug("$control_name started.");    
}

sub stop {
    my $self    = shift;
    
    my $control_name = $self->control_name;
    
    if ( $self->is_server_running ) {

        $self->debug("Stoping $control_name ...");
        $self->pre_shutdown;
        
        kill 2, $self->get_server_pid;
        
        $self->post_shutdown;
        $self->debug("$control_name stopped.");    
        
        return;
    }

    $self->debug("server is not running.");
}

no Moose;
no Moose::Util::TypeConstraints;

1;
__END__