Bump required Module::Install version in everything. janus++
[catagits/Catalyst-Devel.git] / lib / Catalyst / Restarter.pm
CommitLineData
8462f41e 1package Catalyst::Restarter;
2
3use Moose;
4
5use Catalyst::Watcher;
8462f41e 6use namespace::clean -except => 'meta';
7
8has restart_sub => (
9 is => 'ro',
10 isa => 'CodeRef',
11 required => 1,
12);
13
14has _watcher => (
15 is => 'rw',
16 isa => 'Catalyst::Watcher',
17);
18
19has _child => (
20 is => 'rw',
21 isa => 'Int',
22);
23
24sub BUILD {
25 my $self = shift;
26 my $p = shift;
27
28 delete $p->{restart_sub};
29
30 # We could make this lazily, but this lets us check that we
31 # received valid arguments for the watcher up front.
7f564068 32 $self->_watcher( Catalyst::Watcher->instantiate_subclass( %{$p} ) );
8462f41e 33}
34
35sub run_and_watch {
36 my $self = shift;
37
38 $self->_fork_and_start;
39
40 return unless $self->_child;
41
42 $self->_restart_on_changes;
43}
44
45sub _fork_and_start {
46 my $self = shift;
47
48 if ( my $pid = fork ) {
49 $self->_child($pid);
50 }
51 else {
52 $self->restart_sub->();
53 }
54}
55
56sub _restart_on_changes {
57 my $self = shift;
58
7f564068 59 $self->_watcher->watch($self);
60}
8462f41e 61
7f564068 62sub handle_changes {
63 my $self = shift;
64 my @files = @_;
8462f41e 65
7f564068 66 print STDERR "\n";
67 print STDERR "Saw changes to the following files:\n";
68 print STDERR " - $_->{file} ($_->{status})\n" for @files;
69 print STDERR "\n";
70 print STDERR "Attempting to restart the server\n\n";
8462f41e 71
7f564068 72 $self->_kill_child;
8462f41e 73
7f564068 74 $self->_fork_and_start;
8462f41e 75
7f564068 76 $self->_restart_on_changes;
8462f41e 77}
78
02758cf8 79sub _kill_child {
8462f41e 80 my $self = shift;
81
02758cf8 82 return unless $self->_child;
83
84 return unless kill 0, $self->_child;
85
86 local $SIG{CHLD} = 'IGNORE';
87 unless ( kill 'INT', $self->_child ) {
88 # The kill 0 thing does not work on Windows, but the restarter
89 # seems to work fine on Windows with this hack.
90 return if $^O eq 'MSWin32';
91 die "Cannot send INT signal to ", $self->_child, ": $!";
8462f41e 92 }
93}
94
02758cf8 95sub DEMOLISH {
96 my $self = shift;
97
98 $self->_kill_child;
99}
100
8462f41e 101__PACKAGE__->meta->make_immutable;
102
1031;
83d2d4a4 104
105__END__
106
107=head1 NAME
108
109Catalyst::Restarter - Uses Catalyst::Watcher to check for changed files and restart the server
110
111=head1 SYNOPSIS
112
113 my $watcher = Catalyst::Watcher->new(
114 directory => '/path/to/MyApp',
115 regex => '\.yml$|\.yaml$|\.conf|\.pm$',
116 interval => 3,
117 );
118
119 while (1) {
120 my @changed_files = $watcher->watch();
121 }
122
123=head1 DESCRIPTION
124
125This class monitors a directory of files for changes made to any file
126matching a regular expression. It correctly handles new files added to the
127application as well as files that are deleted.
128
129=head1 METHODS
130
131=head2 new ( directory => $path [, regex => $regex, delay => $delay ] )
132
133Creates a new Watcher object.
134
135=head2 find_changed_files
136
137Returns a list of files that have been added, deleted, or changed
138since the last time watch was called. Each element returned is a hash
139reference with two keys. The C<file> key contains the filename, and
140the C<status> key contains one of "modified", "added", or "deleted".
141
142=head1 SEE ALSO
143
144L<Catalyst>, L<Catalyst::Restarter>, <File::Modified>
145
146=head1 AUTHORS
147
148Catalyst Contributors, see Catalyst.pm
149
150=head1 COPYRIGHT
151
152This program is free software, you can redistribute it and/or modify
153it under the same terms as Perl itself.
154
155=cut