1 package MooseX::Runnable::Invocation::Plugin::Restart::Base;
3 use MooseX::Types::Moose qw(Int);
4 use namespace::autoclean;
9 clearer => 'clear_child_pid',
10 predicate => 'has_child_pid',
13 requires 'run_parent_loop';
15 my $is_debug = sub { return 1;
16 $_[0]->meta->does_role('MooseX::Runnable::Invocation::Plugin::Debug');
19 sub _restart_parent_setup {
25 return unless $self->has_child_pid;
26 eval { $self->_debug_message("Restarting...") };
27 kill 'HUP', $self->child_pid;
32 return unless $self->has_child_pid;
33 eval { $self->_debug_message("Killing ", $self->child_pid) };
35 kill 'KILL', $self->child_pid;
36 $self->clear_child_pid;
40 my ($next, $self, @args) = @_;
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;
50 $self->child_pid( $pid );
51 $self->_restart_parent_setup;
53 my $code = $self->run_parent_loop;
54 eval { $self->_debug_message("Shutting down.") };
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)
65 my $child_body; $child_body = sub {
69 # parent? wait for kid to die
70 local $SIG{HUP} = sub {
77 # child? actually do the work
78 exit $self->$next(@args);