our $VERSION = '0.02';
use POSIX 'setsid';
debug => 0,
version => $VERSION,
import => 'class CLASS',
base => 'XAS::Lib::App',
utils => ':process',
constants => 'TRUE FALSE',
accessors => 'daemon pid',
;
# ----------------------------------------------------------------------
# Public Methods
# ----------------------------------------------------------------------
sub define_signals {
my $self = shift;
$SIG{'INT'} = \&signal_handler;
$SIG{'QUIT'} = \&signal_handler;
$SIG{'TERM'} = \&signal_handler;
$SIG{'HUP'} = \&signal_handler;
}
sub define_pidfile {
my $self = shift;
my $script = $self->env->script;
$self->log->debug('entering define_pidfile()');
$self->{pid} = XAS::Lib::Pidfile->new(-pid => $$);
if (my $num = $self->pid->is_running()) {
$self->throw_msg(
dotid($self->class). '.define_pidfile.runerr',
'pid_run_error',
$script, $num
);
}
$self->pid->write() or
$self->throw_msg(
dotid($self->class) . '.define_pidfile.wrterr',
'pid_write_error',
$self->pid->file
);
$self->log->debug('leaving define_pidfile()');
}
sub define_daemon {
my $self = shift;
# become a daemon...
# interesting, "daemonize() if ($self->daemon);" doesn't work as expected
$self->log->debug("before pid = " . $$);
if ($self->daemon) {
daemonize();
}
$self->log->debug("after pid = " . $$);
}
sub run {
my $self = shift;
my $rc = $self->SUPER::run();
$self->pid->remove();
return $rc;
}
# ----------------------------------------------------------------------
# Private Methods
# ----------------------------------------------------------------------
sub _default_options {
my $self = shift;
my $options = $self->SUPER::_default_options();
$self->{daemon} = FALSE;
$options->{'daemon'} = \$self->{daemon};
$options->{'cfgfile=s'} = sub {
my $cfgfile = File($_[1]);
$self->env->cfgfile($cfgfile);
};
$options->{'pidfile=s'} = sub {
my $pidfile = File($_[1]);
$self->env->pidfile($pidfile);
};
return $options;
}
1;
__END__
=head1 NAME
XAS::Lib::App::Daemon - The base class to write daemons within the XAS environment
=head1 SYNOPSIS
use XAS::Lib::App::Daemon;
my $app = XAS::Lib::App::Daemon->new();
$app->run();
=head1 DESCRIPTION
This module defines an operating environment for daemons. A daemon is a
Unix background process without a controlling terminal. Windows really
doesn't have a concept for this behavior. For running background jobs
on Windows please see L<XAS::Lib::App::Services|XAS::Lib::App::Services>.
This module is also single threaded, it doesn't use POE to provide an
async environment. If you need that, then see the above module. This inherits
from L<XAS::Lib::App|XAS::Lib::App>. Please see that module for additional
documentation.
=head1 METHODS
=head2 define_pidfile
This method sets up the pid file for the process. By default, this file
is named $XAS_RUN/<$0>.pid. This can be overridden by the --pidfile option.
=head2 define_signals
This method sets up basic signal handling. By default this is only for the INT,
TERM, HUP and QUIT signals.
=head2 define_daemon
This method will cause the process to become a daemon.
=head1 OPTIONS
This module handles these additional options.
=head2 --cfgfile
This defines an optional configuration file.
=head2 --pidfile
This defines the pid file for recording the pid.
=head2 --daemon
Become a daemon.
=head1 SEE ALSO
=over 4
=item L<XAS|XAS>
=back
=head1 AUTHOR
Kevin L. Esteb, E<lt>kevin@kesteb.usE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2014 Kevin L. Esteb
This is free software; you can redistribute it and/or modify it under
the terms of the Artistic License 2.0. For details, see the full text
=cut