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 )