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',
coerce => 1,
required => 1,
lazy => 1,
- default => sub { Path::Class::Dir->new('var', 'run') },
+ default => sub { Path::Class::Dir->new('', 'var', 'run') },
);
has basedir => (
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 ...
$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);
}
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);
}
$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 . ')');
}
$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);
}
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");
}
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;
# 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!
=head1 NAME
-MooseX::Daemonize - provides a Role that daemonizes your Moose based
-application.
+MooseX::Daemonize - Role for daemonizing your Moose based application
=head1 VERSION
$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
=item I<exit_code Int>
-=item I<status Str>
+=item I<status_message Str>
=back
=item B<status>
+=item B<shutdown>
+
=back
L<Proc::Daemon>, L<Daemon::Generic>
-=head1 AUTHOR
+=head1 AUTHORS
Chris Prather C<< <perigrin@cpan.org> >>
+Stevan Little C<< <stevan.little@iinteractive.com> >>
+
=head1 THANKS
Mike Boyko, Matt S. Trout, Stevan Little, Brandon Black, Ash Berlin and the