use Cwd qw( abs_path );
use File::ChangeNotify;
+use File::Spec;
use FindBin;
use namespace::clean -except => 'meta';
required => 1,
);
+has argv => (
+ is => 'ro',
+ isa => 'ArrayRef',
+ required => 1,
+);
+
has _watcher => (
is => 'rw',
isa => 'File::ChangeNotify::Watcher',
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
+ ];
# We could make this lazily, but this lets us check that we
# received valid arguments for the watcher up front.
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 {
$self->_kill_child;
$self->_fork_and_start;
-
- $self->_restart_on_changes;
}
sub DEMOLISH {
=head1 SYNOPSIS
- my $restarter = Catalyst::Restarter->new(
+ my $class = Catalyst::Restarter->pick_subclass;
+
+ my $restarter = $class->new(
directories => '/path/to/MyApp',
regex => '\.yml$|\.yaml$|\.conf|\.pm$',
start_sub => sub { ... }
=head1 DESCRIPTION
+This is the base class for all restarters, and it also provide
+functionality for picking an appropriate restarter subclass for a
+given platform.
+
This class uses L<File::ChangeNotify> to watch one or more directories
of files and restart the Catalyst server when any of those files
changes.
=head1 METHODS
+=head2 pick_subclass
+
+Returns the name of an appropriate subclass for the given platform.
+
=head2 new ( start_sub => sub { ... }, ... )
-This method creates a new restarter object.
+This method creates a new restarter object, but should be called on a
+subclass, not this class.
The "start_sub" argument is required. This is a subroutine reference
that can be used to start the Catalyst server.