add a lab directory
[gitmo/MooseX-Daemonize.git] / lib / MooseX / Daemonize.pm
CommitLineData
a4952679 1package MooseX::Daemonize;
a392fa53 2use strict; # because Kwalitee is pedantic
a4952679 3use Moose::Role;
4
cbff8e52 5our $VERSION = 0.02;
a4952679 6use Carp;
7use Proc::Daemon;
a392fa53 8
fa2b72a4 9use File::Pid;
10use Moose::Util::TypeConstraints;
a4952679 11
12with qw(MooseX::Getopt);
13
14has progname => (
a392fa53 15 isa => 'Str',
16 is => 'ro',
17 lazy => 1,
18 required => 1,
19 default => sub {
20 ( my $name = lc $_[0]->meta->name ) =~ s/::/_/g;
21 return $name;
22 },
a4952679 23);
24
24a6a660 25has basedir => (
cbff8e52 26 isa => 'Str',
27 is => 'ro',
28 required => 1,
29 lazy => 1,
30 default => sub { return '/' },
24a6a660 31);
32
a4952679 33has pidbase => (
cbff8e52 34 isa => 'Str',
35 is => 'ro',
36 lazy => 1,
37 required => 1,
38 default => sub { return '/var/run' },
a4952679 39);
40
fa2b72a4 41subtype 'Pidfile' => as 'Object' => where { $_->isa('File::Pid') };
cbff8e52 42
43coerce 'Pidfile' => from 'Str' => via { File::Pid->new( { file => $_, } ); };
fa2b72a4 44
a4952679 45has pidfile => (
cbff8e52 46 isa => 'Pidfile',
47 is => 'rw',
48 lazy => 1,
49 required => 1,
50 coerce => 1,
51 predicate => 'has_pidfile',
52 default => sub {
3543c999 53 die 'Cannot write to ' . $_[0]->pidbase unless -w $_[0]->pidbase;
fa2b72a4 54 my $file = $_[0]->pidbase . '/' . $_[0]->progname . '.pid';
55 File::Pid->new( { file => $file } );
56 },
57 handles => {
58 check => 'running',
59 save_pid => 'write',
60 remove_pid => 'remove',
61 get_pid => 'pid',
cbff8e52 62 _pidfile => 'file',
3543c999 63 },
a4952679 64);
65
66has foreground => (
cbff8e52 67 metaclass => 'MooseX::Getopt::Meta::Attribute',
68 cmd_aliases => 'f',
a4952679 69 isa => 'Bool',
70 is => 'ro',
71 default => sub { 0 },
72);
73
cbff8e52 74has is_daemon => (
75 isa => 'Bool',
76 is => 'rw',
77 default => sub { 0 },
78);
79
a392fa53 80sub daemonize {
81 my ($self) = @_;
cbff8e52 82 return if Proc::Daemon::Fork;
a392fa53 83 Proc::Daemon::Init;
cbff8e52 84 $self->is_daemon(1);
a392fa53 85}
86
a4952679 87sub start {
88 my ($self) = @_;
cbff8e52 89 confess "instance already running" if $self->check;
a4952679 90 $self->daemonize unless $self->foreground;
91
cbff8e52 92 return unless $self->is_daemon;
93
94 $self->pidfile->pid($$);
95
3543c999 96 # Avoid 'stdin reopened for output' warning with newer perls
0585edbb 97 ## no critic
3543c999 98 open( NULL, '/dev/null' );
99 <NULL> if (0);
0585edbb 100 ## use critic
fa2b72a4 101
24a6a660 102 # Change to basedir
103 chdir $self->basedir;
fa2b72a4 104
3543c999 105 $self->save_pid;
106 $self->setup_signals;
107 return $$;
108}
109
3543c999 110sub stop {
111 my ( $self, %args ) = @_;
112 my $pid = $self->get_pid;
cecbee2d 113 $self->_kill($pid) unless $self->foreground();
3543c999 114 $self->remove_pid;
115 return 1 if $args{no_exit};
116 exit;
117}
118
a4952679 119sub restart {
120 my ($self) = @_;
7ada91b8 121 $self->stop( no_exit => 1 );
a4952679 122 $self->start();
123}
124
a4952679 125sub setup_signals {
3543c999 126 my ($self) = @_;
127 $SIG{INT} = sub { $self->handle_sigint; };
128 $SIG{HUP} = sub { $self->handle_sighup };
a4952679 129}
130
2361a590 131sub handle_sigint { $_[0]->stop; }
132sub handle_sighup { $_[0]->restart; }
a4952679 133
cecbee2d 134sub _kill {
135 confess "_kill isn't public" unless caller eq __PACKAGE__;
a4952679 136 my ( $self, $pid ) = @_;
2361a590 137 return unless $pid;
3543c999 138 unless ( CORE::kill 0 => $pid ) {
139
140 # warn "$pid already appears dead.";
141 return;
142 }
143
144 if ( $pid eq $$ ) {
145
146 # warn "$pid is us! Can't commit suicied.";
a4952679 147 return;
148 }
149
3543c999 150 CORE::kill( 2, $pid ); # Try SIGINT
2361a590 151 sleep(2) if CORE::kill( 0, $pid );
a4952679 152
3543c999 153 unless ( CORE::kill 0 => $pid or $!{EPERM} ) { # IF it is still running
154 CORE::kill( 15, $pid ); # try SIGTERM
2361a590 155 sleep(2) if CORE::kill( 0, $pid );
a4952679 156 }
157
3543c999 158 unless ( CORE::kill 0 => $pid or $!{EPERM} ) { # IF it is still running
159 CORE::kill( 9, $pid ); # finally try SIGKILL
7ada91b8 160 sleep(3) if CORE::kill( 0, $pid );
a4952679 161 }
162
3543c999 163 unless ( CORE::kill 0 => $pid or $!{EPERM} ) { # IF it is still running
164 carp "$pid doesn't seem to want to die."; # AHH EVIL DEAD!
a4952679 165 }
166
167 return;
168}
169
1701;
171__END__
172
a4952679 173=head1 NAME
174
175MooseX::Daemonize - provides a Role that daemonizes your Moose based application.
176
177
178=head1 VERSION
179
180This document describes MooseX::Daemonize version 0.0.1
181
182
183=head1 SYNOPSIS
184
185 package FileMaker;
186 use Moose;
187 with qw(MooseX::Daemonize);
188
189 sub create_file {
190 my ( $self, $file ) = @_;
191 open( FILE, ">$file" ) || die;
192 close(FILE);
193 }
194
195 no Moose;
196
197 # then in the main package ...
198
199 my $daemon = FileMaker->new();
200 $daemon->start();
201 $daemon->create_file($file);
202 $daemon->stop();
203
204=head1 DESCRIPTION
205
206Often you want to write a persistant daemon that has a pid file, and responds appropriately to Signals.
207This module helps provide the basic infrastructure to do that.
208
209=head1 ATTRIBUTES
210
211=over
212
213=item progname Str
214
cbff8e52 215The name of our daemon, defaults to $self->meta->name =~ s/::/_/;
a4952679 216
217=item pidbase Str
218
219The base for our bid, defaults to /var/run/$progname
220
221=item pidfile Str
222
223The file we store our PID in, defaults to /var/run/$progname/
224
225=item foreground Bool
226
227If true, the process won't background. Useful for debugging. This option can be set via Getopt's -f.
228
229=back
230
231=head1 METHODS
232
233=over
234
235=item check()
236
237Check to see if an instance is already running.
238
239=item start()
240
241Setup a pidfile, fork, then setup the signal handlers.
242
243=item stop()
244
245Stop the process matching the pidfile, and unlinks the pidfile.
246
247=item restart()
248
249Litterally
250
251 $self->stop();
252 $self->start();
253
254=item daemonize()
255
256Calls C<Proc::Daemon::Init> to daemonize this process.
257
258=item kill($pid)
259
260Kills the process for $pid. This will try SIGINT, and SIGTERM before falling back to SIGKILL and finally giving up.
261
262=item setup_signals()
263
264Setup the signal handlers, by default it only sets up handlers for SIGINT and SIGHUP
265
266=item handle_sigint()
267
cecbee2d 268Handle a INT signal, by default calls C<$self->stop()>
a4952679 269
270=item handle_sighup()
271
cecbee2d 272Handle a HUP signal. By default calls C<$self->restart()>
a4952679 273
3543c999 274=item get_pid
275
cecbee2d 276Lookup the pid from our pidfile.
277
3543c999 278=item save_pid
279
cecbee2d 280Save the current pid in our pidfile
281
3543c999 282=item remove_pid
283
cecbee2d 284Delete our pidfile
285
a4952679 286=item meta()
287
cecbee2d 288The C<meta()> method from L<Class::MOP::Class>
a4952679 289
290=back
291
292=head1 DEPENDENCIES
293
294=for author to fill in:
295 A list of all the other modules that this module relies upon,
296 including any restrictions on versions, and an indication whether
297 the module is part of the standard Perl distribution, part of the
298 module's distribution, or must be installed separately. ]
299
fa2b72a4 300Obviously L<Moose>, also L<Carp>, L<Proc::Daemon>, L<File::Pid>
a4952679 301
302=head1 INCOMPATIBILITIES
303
304=for author to fill in:
305 A list of any modules that this module cannot be used in conjunction
306 with. This may be due to name conflicts in the interface, or
307 competition for system or program resources, or due to internal
308 limitations of Perl (for example, many modules that use source code
309 filters are mutually incompatible).
310
311None reported.
312
313
314=head1 BUGS AND LIMITATIONS
315
316=for author to fill in:
317 A list of known problems with the module, together with some
318 indication Whether they are likely to be fixed in an upcoming
319 release. Also a list of restrictions on the features the module
320 does provide: data types that cannot be handled, performance issues
321 and the circumstances in which they may arise, practical
322 limitations on the size of data sets, special cases that are not
323 (yet) handled, etc.
324
325No bugs have been reported.
326
327Please report any bugs or feature requests to
328C<bug-acme-dahut-call@rt.cpan.org>, or through the web interface at
329L<http://rt.cpan.org>.
330
331=head1 SEE ALSO
332
333L<Proc::Daemon>, L<Daemon::Generic>, L<MooseX::Getopt>
334
335=head1 AUTHOR
336
337Chris Prather C<< <perigrin@cpan.org> >>
338
7ada91b8 339=head1 THANKS
340
341Mike Boyko, Matt S. Trout, Stevan Little, Brandon Black, and the #moose denzians
a4952679 342
343=head1 LICENCE AND COPYRIGHT
344
345Copyright (c) 2007, Chris Prather C<< <perigrin@cpan.org> >>. All rights reserved.
346
347This module is free software; you can redistribute it and/or
348modify it under the same terms as Perl itself. See L<perlartistic>.
349
350
351=head1 DISCLAIMER OF WARRANTY
352
353BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
354FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
355OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
356PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
357EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
358WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
359ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
360YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
361NECESSARY SERVICING, REPAIR, OR CORRECTION.
362
363IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
364WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
365REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
366LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
367OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
368THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
369RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
370FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
371SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
372SUCH DAMAGES.