X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine%2FHTTP.pm;h=332e771aaacbd4733612af99cd952b6090d70dd9;hb=31b426c0de28736be8496c4e1efe831ef390bb2f;hp=214877d29942f6c124d1eeb6cd52e1e9880ac0c6;hpb=60c38e3e9076c1ba1b45f4f6c4a768ece8dd3267;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Engine/HTTP.pm b/lib/Catalyst/Engine/HTTP.pm index 214877d..332e771 100644 --- a/lib/Catalyst/Engine/HTTP.pm +++ b/lib/Catalyst/Engine/HTTP.pm @@ -111,11 +111,7 @@ sub read_chunk { sub run { my ( $self, $class, $port, $host, $options ) = @_; - our $GOT_HUP; - local $GOT_HUP = 0; - - local $SIG{HUP} = sub { $GOT_HUP = 1; }; - local $SIG{CHLD} = 'IGNORE'; + $options ||= {}; # Setup restarter my $restarter; @@ -123,31 +119,67 @@ sub run { my $parent = $$; unless ( $restarter = fork ) { + # Prepare + close STDIN; + close STDOUT; + # Index parent directory my $dir = File::Spec->catdir( $FindBin::Bin, '..' ); my $regex = $options->{restart_regex}; - my $one = _index( $dir, $regex ); - while (1) { - sleep $options->{restart_delay}; - my $two = _index( $dir, $regex ); - if ( my $file = _compare_index( $one, $two ) ) { - print STDERR qq/File "$file" modified, restarting\n/; - kill( 1, $parent ); + my $one = _index( $dir, $regex ); + RESTART: while (1) { + sleep $options->{restart_delay} || 1; + + # check if our parent has died + exit if ( getppid == 1 ); + + my $two = _index( $dir, $regex ); + my $changes = _compare_index( $one, $two ); + if (@$changes) { $one = $two; + + # Test modified pm's + for my $file (@$changes) { + next unless $file =~ /\.pm$/; + if ( my $error = _test($file) ) { + print STDERR + qq/File "$file" modified, not restarting\n\n/; + print STDERR '*' x 80, "\n"; + print STDERR $error; + print STDERR '*' x 80, "\n"; + next RESTART; + } + } + + # Restart + my $files = join ', ', @$changes; + print STDERR qq/File(s) "$files" modified, restarting\n\n/; + kill( 1, $parent ); + exit; } } } } + + our $GOT_HUP; + local $GOT_HUP = 0; + + local $SIG{HUP} = sub { $GOT_HUP = 1; }; + local $SIG{CHLD} = 'IGNORE'; # Handle requests # Setup socket $host = $host ? inet_aton($host) : INADDR_ANY; - socket( HTTPDaemon, PF_INET, SOCK_STREAM, getprotobyname('tcp') ); - setsockopt( HTTPDaemon, SOL_SOCKET, SO_REUSEADDR, pack( "l", 1 ) ); - bind( HTTPDaemon, sockaddr_in( $port, $host ) ); - listen( HTTPDaemon, SOMAXCONN ); + socket( HTTPDaemon, PF_INET, SOCK_STREAM, getprotobyname('tcp') ) + || die "Couldn't assign TCP socket: $!"; + setsockopt( HTTPDaemon, SOL_SOCKET, SO_REUSEADDR, pack( "l", 1 ) ) + || die "Couldn't set TCP socket options: $!"; + bind( HTTPDaemon, sockaddr_in( $port, $host ) ) + || die "Couldn't bind socket to $port on $host: $!"; + listen( HTTPDaemon, SOMAXCONN ) + || die "Couldn't listen to socket on $port on $host: $!"; my $url = 'http://'; if ( $host eq INADDR_ANY ) { require Sys::Hostname; @@ -245,21 +277,23 @@ sub run { if ($GOT_HUP) { $SIG{CHLD} = 'DEFAULT'; - exec {$0}( ( ( -x $0 ) ? () : ($^X) ), $0, @ARGV ); + wait; + exec {$0}( ( ( -x $0 ) ? () : ($^X) ), $0, @{ $options->{argv} } ); } } sub _compare_index { my ( $one, $two ) = @_; my %clone = %$two; + my @changes; while ( my ( $key, $val ) = each %$one ) { - return $key if ( !$clone{$key} || ( $clone{$key} ne $val ) ); + if ( !$clone{$key} || ( $clone{$key} ne $val ) ) { + push @changes, $key; + } delete $clone{$key}; } - if ( keys %clone ) { - return join ' ', keys %clone; - } - return 0; + for my $key ( keys %clone ) { push @changes, $key } + return \@changes; } sub _get_line { @@ -296,6 +330,18 @@ sub _index { return \%index; } +sub _test { + my $file = shift; + delete $INC{$file}; + local $SIG{__WARN__} = sub { }; + open my $olderr, '>&STDERR'; + open STDERR, '>', File::Spec->devnull; + eval "require '$file'"; + open STDERR, '>&', $olderr; + return $@ if $@; + return 0; +} + =back =head1 SEE ALSO