X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FDaemonize.pm;h=c67811a2cc3883b85251ad8a11001a6293b50835;hb=4327fe988c1c6e363f8e8a6eeda373e1950fcd17;hp=35c2afe0bf5cf17cb18aee9268a47f654bf26c43;hpb=1ddf8f0c69173810a2e8d9e8dff9d43e97768c0f;p=gitmo%2FMooseX-Daemonize.git diff --git a/lib/MooseX/Daemonize.pm b/lib/MooseX/Daemonize.pm index 35c2afe..c67811a 100644 --- a/lib/MooseX/Daemonize.pm +++ b/lib/MooseX/Daemonize.pm @@ -5,38 +5,39 @@ use MooseX::Types::Path::Class; our $VERSION = 0.05; -with qw[ - MooseX::Daemonize::WithPidFile - MooseX::Getopt -]; +with 'MooseX::Daemonize::WithPidFile', + 'MooseX::Getopt'; has progname => ( - isa => 'Str', - is => 'ro', - lazy => 1, - required => 1, - default => sub { + metaclass => 'Getopt', + isa => 'Str', + is => 'ro', + lazy => 1, + required => 1, + default => sub { ( my $name = lc $_[0]->meta->name ) =~ s/::/_/g; return $name; }, ); has pidbase => ( - isa => 'Path::Class::Dir', - is => 'ro', - coerce => 1, - required => 1, - lazy => 1, - default => sub { Path::Class::Dir->new('var', 'run') }, + metaclass => 'Getopt', + isa => 'Path::Class::Dir', + is => 'ro', + coerce => 1, + required => 1, + lazy => 1, + default => sub { Path::Class::Dir->new('var', 'run') }, ); has basedir => ( - isa => 'Path::Class::Dir', - is => 'ro', - coerce => 1, - required => 1, - lazy => 1, - default => sub { Path::Class::Dir->new('/') }, + metaclass => 'Getopt', + isa => 'Path::Class::Dir', + is => 'ro', + coerce => 1, + required => 1, + lazy => 1, + default => sub { Path::Class::Dir->new('/') }, ); has foreground => ( @@ -48,11 +49,16 @@ has foreground => ( ); has stop_timeout => ( - isa => 'Int', - is => 'rw', - default => sub { 2 } + metaclass => 'Getopt', + isa => 'Int', + is => 'rw', + default => sub { 2 } ); +# methods ... + +## PID file related stuff ... + sub init_pidfile { my $self = shift; my $file = $self->pidbase . '/' . $self->progname . '.pid'; @@ -60,6 +66,25 @@ sub init_pidfile { MooseX::Daemonize::Pid::File->new( file => $file ); } +# backwards compat, +sub check { (shift)->pidfile->is_running } +sub save_pid { (shift)->pidfile->write } +sub remove_pid { (shift)->pidfile->remove } +sub get_pid { (shift)->pidfile->pid } + +## signal handling ... + +sub setup_signals { + my $self = shift; + $SIG{'INT'} = sub { $self->handle_sigint }; + $SIG{'HUP'} = sub { $self->handle_sighup }; +} + +sub handle_sigint { $_[0]->stop; } +sub handle_sighup { $_[0]->restart; } + +## daemon control methods ... + sub start { my ($self) = @_; @@ -69,12 +94,7 @@ sub start { return unless $self->is_daemon; - $self->pidfile->pid($$); - - # Avoid 'stdin reopened for output' - # warning with newer perls - open( NULL, '/dev/null' ); - if (0); + $self->pidfile->pid($$); # Change to basedir chdir $self->basedir; @@ -84,6 +104,12 @@ sub start { return $$; } +sub restart { + my ($self) = @_; + $self->stop( no_exit => 1 ); + $self->start(); +} + # Make _kill *really* private my $_kill; @@ -96,21 +122,6 @@ sub stop { exit; } -sub restart { - my ($self) = @_; - $self->stop( no_exit => 1 ); - $self->start(); -} - -sub setup_signals { - my $self = shift; - $SIG{'INT'} = sub { $self->handle_sigint }; - $SIG{'HUP'} = sub { $self->handle_sighup }; -} - -sub handle_sigint { $_[0]->stop; } -sub handle_sighup { $_[0]->restart; } - $_kill = sub { my ( $self, $pid ) = @_; return unless $pid; @@ -165,103 +176,162 @@ application. =head1 VERSION -This document describes MooseX::Daemonize version 0.04 +This document describes MooseX::Daemonize version 0.05 =head1 SYNOPSIS - package FileMaker; + package My::Daemon; use Moose; + with qw(MooseX::Daemonize); + + # ... define your class .... + + after start => sub { + my $self = shift; + return unless $self->is_daemon; + # your daemon code here ... + }; - sub create_file { - my ( $self, $file ) = @_; - open( FILE, ">$file" ) || die; - close(FILE); - } - - no Moose; - - # then in the main package ... + # then in your script ... + + my $daemon = My::Daemon->new_with_options(); - my $daemon = FileMaker->new(); - $daemon->start(); - $daemon->create_file($file); - $daemon->stop(); + my ($command) = @{$daemon->extra_argv} + defined $command || die "No command specified"; + + $daemon->start() if $command eq 'start'; + $daemon->stop() if $command eq 'stop'; =head1 DESCRIPTION Often you want to write a persistant daemon that has a pid file, and responds -appropriately to Signals. This module helps provide the basic infrastructure -to do that. +appropriately to Signals. This module provides a set of basic roles as an +infrastructure to do that. =head1 ATTRIBUTES +This list includes attributes brought in from other roles as well +we include them here for ease of documentation. All of these attributes +are settable though L's command line handling, with the +exception of C. + =over -=item progname Path::Class::Dir | Str +=item I -The name of our daemon, defaults to $self->meta->name =~ s/::/_/; +The name of our daemon, defaults to C<$package_name =~ s/::/_/>; -=item pidbase Path::Class::Dir | Str +=item I -The base for our bid, defaults to /var/run/$progname +The base for our bid, defaults to C -=item pidfile MooseX::Daemonize::Pid::File | Str +=item I -The file we store our PID in, defaults to /var/run/$progname +The file we store our PID in, defaults to C -=item foreground Bool +=item I If true, the process won't background. Useful for debugging. This option can be set via Getopt's -f. -=item is_daemon Bool +=item I + +If true, the process is the backgrounded daemon process, if false it is the +parent process. This is useful for example in an C sub { }> +block. -If true, the process is the backgrounded process. This is useful for example -in an after 'start' => sub { } block +B This option is explicitly B available through L. -=item stop_timeout +=item I Number of seconds to wait for the process to stop, before trying harder to kill -it. Defaults to 2 seconds +it. Defaults to 2 seconds. =back =head1 METHODS -=over +=head2 Daemon Control Methods + +These methods can be used to control the daemon behavior. Every effort +has been made to have these methods DWIM (Do What I Mean), so that you +can focus on just writing the code for your daemon. -=item start() +Extending these methods is best done with the L method modifiers, +such as C, C and C. + +=over 4 + +=item B Setup a pidfile, fork, then setup the signal handlers. -=item stop() +=item B Stop the process matching the pidfile, and unlinks the pidfile. -=item restart() +=item B -Litterally +Literally this is: $self->stop(); $self->start(); -=item daemonize() +=back + +=head2 Pidfile Handling Methods + +=over 4 + +=item B + +This method will create a L object and tell +it to store the PID in the file C<$pidbase/$progname.pid>. + +=item B + +This checks to see if the daemon process is currently running by checking +the pidfile. -Calls daemonize from MooseX::Daemonize::Core. +=item B -=item setup_signals() +Returns the PID of the daemon process. -Setup the signal handlers, by default it only sets up handlers for SIGINT and SIGHUP +=item B -=item handle_sigint() +Write the pidfile. + +=item B + +Removes the pidfile. + +=back + +=head2 Signal Handling Methods + +=over 4 + +=item B + +Setup the signal handlers, by default it only sets up handlers for SIGINT and +SIGHUP. If you wish to add more signals just use the C method modifier +and add them. + +=item B Handle a INT signal, by default calls C<$self->stop()> -=item handle_sighup() +=item B Handle a HUP signal. By default calls C<$self->restart()> +=back + +=head2 Introspection + +=over 4 + =item meta() The C method from L @@ -270,37 +340,14 @@ The C method from L =head1 DEPENDENCIES -=for author to fill in: - A list of all the other modules that this module relies upon, - including any restrictions on versions, and an indication whether - the module is part of the standard Perl distribution, part of the - module's distribution, or must be installed separately. ] - -Obviously L, and L +L, L, L and L =head1 INCOMPATIBILITIES -=for author to fill in: - A list of any modules that this module cannot be used in conjunction - with. This may be due to name conflicts in the interface, or - competition for system or program resources, or due to internal - limitations of Perl (for example, many modules that use source code - filters are mutually incompatible). - -None reported. - +None reported. Although obviously this will not work on Windows. =head1 BUGS AND LIMITATIONS -=for author to fill in: - A list of known problems with the module, together with some - indication Whether they are likely to be fixed in an upcoming - release. Also a list of restrictions on the features the module - does provide: data types that cannot be handled, performance issues - and the circumstances in which they may arise, practical - limitations on the size of data sets, special cases that are not - (yet) handled, etc. - No bugs have been reported. Please report any bugs or feature requests to @@ -309,7 +356,7 @@ L. =head1 SEE ALSO -L, L, L +L, L =head1 AUTHOR @@ -330,7 +377,6 @@ reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. - =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY