avoid unnecessary call to kill if kid already died
[gitmo/MooseX-Runnable.git] / lib / MooseX / Runnable / Invocation / Plugin / Restart / Base.pm
CommitLineData
d69f95ab 1package MooseX::Runnable::Invocation::Plugin::Restart::Base;
2use Moose::Role;
3use MooseX::Types::Moose qw(Int);
4use namespace::autoclean;
5
6has 'child_pid' => (
7 is => 'rw',
8 isa => Int,
9 clearer => 'clear_child_pid',
10 predicate => 'has_child_pid',
11);
12
13requires 'run_parent_loop';
14
15my $is_debug = sub { return 1;
16 $_[0]->meta->does_role('MooseX::Runnable::Invocation::Plugin::Debug');
17};
18
19sub _restart_parent_setup {
20 my $self = shift;
21}
22
23sub restart {
24 my $self = shift;
25 return unless $self->has_child_pid;
26 eval { $self->_debug_message("Restarting...") };
27 kill 'HUP', $self->child_pid;
28}
29
30sub kill_child {
31 my $self = shift;
32 return unless $self->has_child_pid;
33 eval { $self->_debug_message("Killing ", $self->child_pid) };
34
35 kill 'KILL', $self->child_pid;
36 $self->clear_child_pid;
37}
38
39around 'run' => sub {
40 my ($next, $self, @args) = @_;
41 my $pid = fork();
42 if($pid){
c15146cc 43 local $SIG{CHLD} = sub {
44 # handle the case where the child dies unexpectedly
45 waitpid $self->child_pid, 0;
46 $self->clear_child_pid;
47 };
d69f95ab 48
49 # parent
50 $self->child_pid( $pid );
51 $self->_restart_parent_setup;
52
53 my $code = $self->run_parent_loop;
54 eval { $self->_debug_message("Shutting down.") };
55
56 $self->kill_child;
57 return $code;
58 }
59 else {
60 # we go to all this effort so that the child process is always
61 # free of any "infection" by the parent (like the event loop,
62 # used by the parent to receive filesystem events or signals,
63 # which can't be cancelled by the child)
64
65 my $child_body; $child_body = sub {
66 while(1){
67 my $pid2 = fork;
68 if($pid2){
69 # parent? wait for kid to die
70 local $SIG{HUP} = sub {
71 kill 'KILL', $pid2;
72 };
73 waitpid $pid2, 0;
74 $child_body->();
75 }
76 else {
77 # child? actually do the work
78 exit $self->$next(@args);
79
80 }
81 }
82 };
83
84 $child_body->();
85 }
86};
87
881;