Catalyst::Restarter::Forking: clear watcher in child process
[catagits/Catalyst-Devel.git] / lib / Catalyst / Restarter.pm
index e83b46a..81295f1 100644 (file)
@@ -6,6 +6,7 @@ use Cwd qw( abs_path );
 use File::ChangeNotify;
 use File::Spec;
 use FindBin;
+use Catalyst::Utils;
 use namespace::clean -except => 'meta';
 
 has start_sub => (
@@ -21,8 +22,14 @@ has argv =>  (
 );
 
 has _watcher => (
-    is  => 'rw',
-    isa => 'File::ChangeNotify::Watcher',
+    is      => 'rw',
+    isa     => 'File::ChangeNotify::Watcher',
+    clearer => '_clear_watcher',
+);
+
+has _filter => (
+    is      => 'rw',
+    isa     => 'RegexpRef',
 );
 
 has _child => (
@@ -43,8 +50,7 @@ sub pick_subclass {
 
     $subclass = 'Catalyst::Restarter::' . $subclass;
 
-    eval "use $subclass";
-    die $@ if $@;
+    Catalyst::Utils::ensure_class_loaded($subclass);
 
     return $subclass;
 }
@@ -69,6 +75,10 @@ sub BUILD {
         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.
     $self->_watcher( File::ChangeNotify->instantiate_watcher( %{$p} ) );
@@ -101,22 +111,38 @@ 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->_kill_child;
+
+        $self->_fork_and_start;
+    }
 }
 
 sub DEMOLISH {
@@ -179,7 +205,7 @@ the child, forks again, and starts a new server.
 
 =head1 SEE ALSO
 
-L<Catalyst>, <File::ChangeNotify>
+L<Catalyst>, L<File::ChangeNotify>
 
 =head1 AUTHORS