X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FRestarter.pm;h=c08517a038ac3bd77523562383a898354db10f11;hb=caa3831b235973486da12d912a9f6176c6c4f0aa;hp=7a7c6ffa2ade65cf2d70a86775f7497a15f056ce;hpb=5ad5350a3aec742ee638fabbc4a8e9fa2c806311;p=catagits%2FCatalyst-Devel.git diff --git a/lib/Catalyst/Restarter.pm b/lib/Catalyst/Restarter.pm index 7a7c6ff..c08517a 100644 --- a/lib/Catalyst/Restarter.pm +++ b/lib/Catalyst/Restarter.pm @@ -4,6 +4,7 @@ use Moose; use Cwd qw( abs_path ); use File::ChangeNotify; +use File::Spec; use FindBin; use namespace::clean -except => 'meta'; @@ -24,6 +25,11 @@ has _watcher => ( isa => 'File::ChangeNotify::Watcher', ); +has _filter => ( + is => 'rw', + isa => 'RegexpRef', +); + has _child => ( is => 'rw', isa => 'Int', @@ -54,8 +60,23 @@ sub BUILD { delete $p->{start_sub}; - $p->{filter} ||= qr/(?:\/|^)(?!\.\#).+(?:\.yml$|\.yaml$|\.conf|\.pm)$/; - $p->{directories} ||= abs_path( File::Spec->catdir( $FindBin::Bin, '..' ) ); + $p->{filter} ||= qr/(?:\/|^)(?![.#_]).+(?:\.yml$|\.yaml$|\.conf|\.pm)$/; + + my $app_root = abs_path( File::Spec->catdir( $FindBin::Bin, '..' ) ); + + # Monitor application root dir + $p->{directories} ||= $app_root; + + # exclude t/, root/ and hidden dirs + $p->{exclude} ||= [ + File::Spec->catdir($app_root, 't'), + File::Spec->catdir($app_root, 'root'), + qr(/\.[^/]*/?$), # match hidden dirs + ]; + + # keep filter regexp to make sure we don't restart on deleted + # files or directories where we can't check -d + $self->_filter( $p->{filter} ); # We could make this lazily, but this lets us check that we # received valid arguments for the watcher up front. @@ -75,32 +96,50 @@ sub run_and_watch { sub _restart_on_changes { my $self = shift; - my @events = $self->_watcher->wait_for_events(); - $self->_handle_events(@events); + # We use this loop in order to avoid having _handle_events() call back + # into this method. We used to do that, and the end result was that stack + # traces became longer and longer with every restart. Using this loop, the + # portion of the stack trace that covers this code does not grow. + while (1) { + my @events = $self->_watcher->wait_for_events(); + $self->_handle_events(@events); + } } sub _handle_events { my $self = shift; my @events = @_; - print STDERR "\n"; - print STDERR "Saw changes to the following files:\n"; - + my @files; + # Filter out any events which are the creation / deletion of directories + # so that creating an empty directory won't cause a restart for my $event (@events) { my $path = $event->path(); my $type = $event->type(); - - print STDERR " - $path ($type)\n"; + if ( ( $type ne 'delete' && -f $path ) + || ( $type eq 'delete' && $path =~ $self->_filter ) ) + { + push @files, { path => $path, type => $type }; + } } - print STDERR "\n"; - print STDERR "Attempting to restart the server\n\n"; + if (@files) { + print STDERR "\n"; + print STDERR "Saw changes to the following files:\n"; - $self->_kill_child; + for my $f (@files) { + my $path = $f->{path}; + my $type = $f->{type}; + print STDERR " - $path ($type)\n"; + } - $self->_fork_and_start; + print STDERR "\n"; + print STDERR "Attempting to restart the server\n\n"; - $self->_restart_on_changes; + $self->_kill_child; + + $self->_fork_and_start; + } } sub DEMOLISH { @@ -163,7 +202,7 @@ the child, forks again, and starts a new server. =head1 SEE ALSO -L, +L, L =head1 AUTHORS