1 package Catalyst::Restarter;
5 use Cwd qw( abs_path );
6 use File::ChangeNotify;
9 use namespace::clean -except => 'meta';
25 isa => 'File::ChangeNotify::Watcher',
38 defined $ENV{CATALYST_RESTARTER}
39 ? $ENV{CATALYST_RESTARTER}
44 $subclass = 'Catalyst::Restarter::' . $subclass;
56 delete $p->{start_sub};
58 $p->{filter} ||= qr/(?:\/|^)(?![.#_]).+(?:\.yml$|\.yaml$|\.conf|\.pm)$/;
60 my $app_root = abs_path( File::Spec->catdir( $FindBin::Bin, '..' ) );
62 # Monitor application root dir
63 $p->{directories} ||= $app_root;
65 # exclude t/, root/ and hidden dirs
67 File::Spec->catdir($app_root, 't'),
68 File::Spec->catdir($app_root, 'root'),
69 qr(/\.[^/]*/?$), # match hidden dirs
72 # We could make this lazily, but this lets us check that we
73 # received valid arguments for the watcher up front.
74 $self->_watcher( File::ChangeNotify->instantiate_watcher( %{$p} ) );
80 $self->_fork_and_start;
82 return unless $self->_child;
84 $self->_restart_on_changes;
87 sub _restart_on_changes {
90 # We use this loop in order to avoid having _handle_events() call back
91 # into this method. We used to do that, and the end result was that stack
92 # traces became longer and longer with every restart. Using this loop, the
93 # portion of the stack trace that covers this code does not grow.
95 my @events = $self->_watcher->wait_for_events();
96 $self->_handle_events(@events);
105 print STDERR "Saw changes to the following files:\n";
107 for my $event (@events) {
108 my $path = $event->path();
109 my $type = $event->type();
111 print STDERR " - $path ($type)\n";
115 print STDERR "Attempting to restart the server\n\n";
119 $self->_fork_and_start;
128 __PACKAGE__->meta->make_immutable;
136 Catalyst::Restarter - Uses File::ChangeNotify to check for changed files and restart the server
140 my $class = Catalyst::Restarter->pick_subclass;
142 my $restarter = $class->new(
143 directories => '/path/to/MyApp',
144 regex => '\.yml$|\.yaml$|\.conf|\.pm$',
145 start_sub => sub { ... }
148 $restarter->run_and_watch;
152 This is the base class for all restarters, and it also provide
153 functionality for picking an appropriate restarter subclass for a
156 This class uses L<File::ChangeNotify> to watch one or more directories
157 of files and restart the Catalyst server when any of those files
164 Returns the name of an appropriate subclass for the given platform.
166 =head2 new ( start_sub => sub { ... }, ... )
168 This method creates a new restarter object, but should be called on a
169 subclass, not this class.
171 The "start_sub" argument is required. This is a subroutine reference
172 that can be used to start the Catalyst server.
176 This method forks, starts the server in a child process, and then
177 watched for changed files in the parent. When files change, it kills
178 the child, forks again, and starts a new server.
182 L<Catalyst>, <File::ChangeNotify>
186 Catalyst Contributors, see Catalyst.pm
190 This program is free software, you can redistribute it and/or modify
191 it under the same terms as Perl itself.