X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FDaemonize.pm;h=ba46d4db36b4351604bee1c822a5c56248501b5a;hb=b38ab84f7a1b83212eefcb2e7f876c42b8dbfb24;hp=b16877d95995f2d127a8ff30de5bc91e06857947;hpb=5b9ebe08eff2f6410804c2f3c2fa361db0b446a2;p=gitmo%2FMooseX-Daemonize.git diff --git a/lib/MooseX/Daemonize.pm b/lib/MooseX/Daemonize.pm index b16877d..ba46d4d 100644 --- a/lib/MooseX/Daemonize.pm +++ b/lib/MooseX/Daemonize.pm @@ -3,10 +3,13 @@ use strict; # because Kwalitee is pedantic use Moose::Role; use MooseX::Types::Path::Class; -our $VERSION = 0.05; +our $VERSION = 0.06; with 'MooseX::Daemonize::WithPidFile', 'MooseX::Getopt'; + +use constant OK => 0; +use constant ERROR => 1; has progname => ( metaclass => 'Getopt', @@ -27,7 +30,7 @@ has pidbase => ( coerce => 1, required => 1, lazy => 1, - default => sub { Path::Class::Dir->new('var', 'run') }, + default => sub { Path::Class::Dir->new('', 'var', 'run') }, ); has basedir => ( @@ -92,12 +95,16 @@ sub get_pid { (shift)->pidfile->pid } sub setup_signals { my $self = shift; - $SIG{'INT'} = sub { $self->handle_sigint }; - $SIG{'HUP'} = sub { $self->handle_sighup }; + $SIG{'INT'} = sub { $self->shutdown }; +# I can't think of a sane default here really ... +# $SIG{'HUP'} = sub { $self->handle_sighup }; } -sub handle_sigint { $_[0]->stop } -sub handle_sighup { $_[0]->restart } +sub shutdown { + my $self = shift; + $self->pidfile->remove if $self->pidfile->pid == $$; + exit(0); +} ## daemon control methods ... @@ -108,7 +115,8 @@ sub start { $self->clear_exit_code; if ($self->pidfile->is_running) { - $self->status_message('Daemon is already running with pid (' . $self->pidfile->pid . ')'); + $self->exit_code(OK); + $self->status_message('Daemon is already running with pid (' . $self->pidfile->pid . ')'); return !($self->exit_code); } @@ -118,13 +126,14 @@ sub start { else { eval { $self->daemonize }; if ($@) { - $self->exit_code(1); + $self->exit_code(ERROR); $self->status_message('Start failed : ' . $@); return !($self->exit_code); } } unless ($self->is_daemon) { + $self->exit_code(OK); $self->status_message('Start succeeded'); return !($self->exit_code); } @@ -146,10 +155,11 @@ sub status { $self->clear_exit_code; if ($self->pidfile->is_running) { + $self->exit_code(OK); $self->status_message('Daemon is running with pid (' . $self->pidfile->pid . ')'); } else { - $self->exit_code(1); + $self->exit_code(ERROR); $self->status_message('Daemon is not running with pid (' . $self->pidfile->pid . ')'); } @@ -163,17 +173,19 @@ sub restart { $self->clear_exit_code; unless ($self->stop) { - $self->exit_code(1); + $self->exit_code(ERROR); $self->status_message('Restart (Stop) failed : ' . $@); } unless ($self->start) { - $self->exit_code(1); + $self->exit_code(ERROR); $self->status_message('Restart (Start) failed : ' . $@); } - $self->status_message("Restart successful") - if !$self->exit_code; + if ($self->exit_code == OK) { + $self->exit_code(OK); + $self->status_message("Restart successful"); + } return !($self->exit_code); } @@ -201,29 +213,22 @@ sub stop { eval { $self->$_kill($self->pidfile->pid) }; # and complain if we can't ... if ($@) { - $self->exit_code(1); + $self->exit_code(ERROR); $self->status_message('Stop failed : ' . $@); } # or gloat if we succeed .. else { + $self->exit_code(OK); $self->status_message('Stop succeeded'); } } - - # clean up ... - eval { $self->pidfile->remove }; - if ($@) { - warn "Could not remove pidfile (" - . $self->pidfile->file - . ") because : $!"; - } - } else { # this just returns the OK # exit code for now, but # we should make this overridable + $self->exit_code(OK); $self->status_message("Not running"); } @@ -237,15 +242,12 @@ $_kill = sub { my ( $self, $pid ) = @_; return unless $pid; unless ( CORE::kill 0 => $pid ) { - # warn "$pid already appears dead."; return; } if ( $pid eq $$ ) { - - # warn "$pid is us! Can't commit suicide."; - return; + die "$pid is us! Can't commit suicide."; } my $timeout = $self->stop_timeout; @@ -253,32 +255,39 @@ $_kill = sub { # kill 0 => $pid returns 0 if the process is dead # $!{EPERM} could also be true if we cant kill it (permission error) - # if this is being called - # inside the daemon then - # we don't want sig-INT to - # fall into a loop here - # so we reset it. - if ($self->is_daemon) { - $SIG{INT} = 'DEFAULT'; - } - # Try SIGINT ... 2s ... SIGTERM ... 2s ... SIGKILL ... 3s ... UNDEAD! + my $terminating_signal; for ( [ 2, $timeout ], [15, $timeout], [9, $timeout * 1.5] ) { my ($signal, $timeout) = @$_; $timeout = int $timeout; CORE::kill($signal, $pid); - last unless CORE::kill 0 => $pid or $!{EPERM}; - while ($timeout) { - sleep(1); - last unless CORE::kill 0 => $pid or $!{EPERM}; + unless(CORE::kill 0 => $pid or $!{EPERM}) { + $terminating_signal = $signal; + last; + } $timeout--; + sleep(1) if $timeout; } + + last if $terminating_signal; } - return unless ( CORE::kill 0 => $pid or $!{EPERM} ); + if($terminating_signal) { + if($terminating_signal == 9) { + # clean up the pidfile ourselves iff we used -9 and it worked + warn "Had to resort to 'kill -9' and it worked, wiping pidfile"; + eval { $self->pidfile->remove }; + if ($@) { + warn "Could not remove pidfile (" + . $self->pidfile->file + . ") because : $!"; + } + } + return; + } # IF it is still running Carp::carp "$pid doesn't seem to want to die."; # AHH EVIL DEAD! @@ -291,8 +300,7 @@ __END__ =head1 NAME -MooseX::Daemonize - provides a Role that daemonizes your Moose based -application. +MooseX::Daemonize - Role for daemonizing your Moose based application =head1 VERSION @@ -325,7 +333,7 @@ This document describes MooseX::Daemonize version 0.05 $daemon->restart if $command eq 'restart'; $daemon->stop if $command eq 'stop'; - warn($daemon->status); + warn($daemon->status_message); exit($daemon->exit_code); =head1 DESCRIPTION @@ -381,7 +389,7 @@ These are the internal attributes, which are not available through MooseX::Getop =item I -=item I +=item I =back @@ -415,6 +423,8 @@ Literally this is: =item B +=item B + =back @@ -496,10 +506,12 @@ L. L, L -=head1 AUTHOR +=head1 AUTHORS Chris Prather C<< >> +Stevan Little C<< >> + =head1 THANKS Mike Boyko, Matt S. Trout, Stevan Little, Brandon Black, Ash Berlin and the