Tidy up dependencies
[catagits/Catalyst-Devel.git] / lib / Catalyst / Restarter.pm
CommitLineData
8462f41e 1package Catalyst::Restarter;
8462f41e 2use Moose;
3
ffbcd711 4use Cwd qw( abs_path );
a13b99da 5use File::ChangeNotify;
ffbcd711 6use FindBin;
cf042872 7use namespace::autoclean;
8462f41e 8
b8e3feb1 9has start_sub => (
8462f41e 10 is => 'ro',
11 isa => 'CodeRef',
12 required => 1,
13);
14
15has _watcher => (
16 is => 'rw',
a13b99da 17 isa => 'File::ChangeNotify::Watcher',
8462f41e 18);
19
20has _child => (
21 is => 'rw',
22 isa => 'Int',
23);
24
2e9609df 25sub pick_subclass {
26 my $class = shift;
27
28 my $subclass;
29 $subclass =
30 defined $ENV{CATALYST_RESTARTER}
31 ? $ENV{CATALYST_RESTARTER}
32 : $^O eq 'MSWin32'
33 ? 'Win32'
34 : 'Forking';
35
36 $subclass = 'Catalyst::Restarter::' . $subclass;
37
38 eval "use $subclass";
39 die $@ if $@;
40
41 return $subclass;
42}
43
8462f41e 44sub BUILD {
45 my $self = shift;
46 my $p = shift;
47
b8e3feb1 48 delete $p->{start_sub};
8462f41e 49
a13b99da 50 $p->{filter} ||= qr/(?:\/|^)(?!\.\#).+(?:\.yml$|\.yaml$|\.conf|\.pm)$/;
ffbcd711 51 $p->{directories} ||= abs_path( File::Spec->catdir( $FindBin::Bin, '..' ) );
a13b99da 52
8462f41e 53 # We could make this lazily, but this lets us check that we
54 # received valid arguments for the watcher up front.
a13b99da 55 $self->_watcher( File::ChangeNotify->instantiate_watcher( %{$p} ) );
8462f41e 56}
57
58sub run_and_watch {
59 my $self = shift;
60
61 $self->_fork_and_start;
62
63 return unless $self->_child;
64
65 $self->_restart_on_changes;
66}
67
8462f41e 68sub _restart_on_changes {
69 my $self = shift;
70
a13b99da 71 my @events = $self->_watcher->wait_for_events();
72 $self->_handle_events(@events);
7f564068 73}
8462f41e 74
a13b99da 75sub _handle_events {
76 my $self = shift;
77 my @events = @_;
8462f41e 78
7f564068 79 print STDERR "\n";
80 print STDERR "Saw changes to the following files:\n";
a13b99da 81
82 for my $event (@events) {
83 my $path = $event->path();
84 my $type = $event->type();
85
86 print STDERR " - $path ($type)\n";
87 }
88
7f564068 89 print STDERR "\n";
90 print STDERR "Attempting to restart the server\n\n";
8462f41e 91
7f564068 92 $self->_kill_child;
8462f41e 93
7f564068 94 $self->_fork_and_start;
8462f41e 95
7f564068 96 $self->_restart_on_changes;
8462f41e 97}
98
02758cf8 99sub DEMOLISH {
100 my $self = shift;
101
102 $self->_kill_child;
103}
104
8462f41e 105__PACKAGE__->meta->make_immutable;
106
1071;
83d2d4a4 108
109__END__
110
111=head1 NAME
112
b8e3feb1 113Catalyst::Restarter - Uses File::ChangeNotify to check for changed files and restart the server
83d2d4a4 114
115=head1 SYNOPSIS
116
36ff1319 117 my $class = Catalyst::Restarter->pick_subclass;
118
119 my $restarter = $class->new(
b8e3feb1 120 directories => '/path/to/MyApp',
121 regex => '\.yml$|\.yaml$|\.conf|\.pm$',
122 start_sub => sub { ... }
83d2d4a4 123 );
124
b8e3feb1 125 $restarter->run_and_watch;
83d2d4a4 126
127=head1 DESCRIPTION
128
36ff1319 129This is the base class for all restarters, and it also provide
130functionality for picking an appropriate restarter subclass for a
131given platform.
132
b8e3feb1 133This class uses L<File::ChangeNotify> to watch one or more directories
134of files and restart the Catalyst server when any of those files
135changes.
83d2d4a4 136
137=head1 METHODS
138
36ff1319 139=head2 pick_subclass
140
141Returns the name of an appropriate subclass for the given platform.
142
b8e3feb1 143=head2 new ( start_sub => sub { ... }, ... )
144
36ff1319 145This method creates a new restarter object, but should be called on a
146subclass, not this class.
83d2d4a4 147
b8e3feb1 148The "start_sub" argument is required. This is a subroutine reference
149that can be used to start the Catalyst server.
83d2d4a4 150
b8e3feb1 151=head2 run_and_watch
83d2d4a4 152
b8e3feb1 153This method forks, starts the server in a child process, and then
154watched for changed files in the parent. When files change, it kills
155the child, forks again, and starts a new server.
83d2d4a4 156
157=head1 SEE ALSO
158
b8e3feb1 159L<Catalyst>, <File::ChangeNotify>
83d2d4a4 160
161=head1 AUTHORS
162
163Catalyst Contributors, see Catalyst.pm
164
165=head1 COPYRIGHT
166
167This program is free software, you can redistribute it and/or modify
168it under the same terms as Perl itself.
169
170=cut