—package
XAS::Lib::App::Daemon;
our
$VERSION
=
'0.02'
;
use
Try::Tiny;
use
Pod::Usage;
use
Hash::Merge;
use
Getopt::Long;
use
XAS::Lib::Pidfile;
use
XAS::Class
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
of the license at http://www.perlfoundation.org/artistic_license_2_0.
=cut