App-DuckPAN
view release on metacpan or search on metacpan
lib/App/DuckPAN/Restart.pm view on Meta::CPAN
package App::DuckPAN::Restart;
our $AUTHORITY = 'cpan:DDG';
# ABSTRACT: Automatic restarting of application on file change
$App::DuckPAN::Restart::VERSION = '1021';
use File::Find::Rule;
use Filesys::Notify::Simple;
use App::DuckPAN::TemplateDefinitions;
use Try::Tiny;
use strict;
use Moo::Role;
requires '_run_app';
sub run_restarter {
my ($self, $args) = @_;
# exit immediately if not in an IA directory
$self->app->get_ia_type;
# will keep (re)starting the server until the app exits
while(1){
defined(my $app = fork) or die 'Failed to fork application';
unless($app){ # app kid
$self->_run_app($args);
exit 0;
}
# Slightly different format here since we need to take care of
# the newly spawned app on failure.
my $fmon = fork;
unless($fmon){ # file monitor kid
unless(defined $fmon){
kill SIGTERM => $app;
die 'Failed to fork file monitor';
}
$self->_monitor_directories;
exit 0;
}
# wait for one them to exit. -1 waits for all children
my $pid = waitpid -1, 0;
# reload the application
if($pid == $fmon){
# if we can't kill the app, let's not start another
unless(kill SIGTERM => $app){
die "Failed to kill the application (pid: $app). Check manually";
}
# wait for it, otherwise the next whie loop will get it
waitpid($app, 0);
}
elsif($pid == $app){ # or exit
kill SIGTERM => $fmon;
exit;
}
else{ die "Unknown kid $pid reaped!\n"; } # shouldn't happen
}
}
sub _get_directories_to_monitor {
my $self = shift;
my @output_dirs;
try {
my $template_defs = App::DuckPAN::TemplateDefinitions->new;
my @templates = $template_defs->get_templates;
( run in 2.002 seconds using v1.01-cache-2.11-cpan-6aa56a78535 )