NAME
CTK::Daemon - Abstract class to implement Daemons
VERSION
Version 1.04
SYNOPSIS
use base qw/CTK::Daemon/;
sub new {
my $class = shift;
# ... your code ...
$class->SUPER::new(shift, @_);
}
sub run {
my $self = shift;
my $logger = $self->logger;
$logger->log_info("Code is running");
my $step = 5;
while ($self->ok) { # Check it every time
# If occurred usual error:
# $logger->log_error("...");
# mysleep SLEEP;
# next;
# If occurred exception error
# $logger->log_crit("...");
# $self->exception(1);
# last;
# For skip this loop
# $self->skip(1);
# next;
last unless $self->ok; # Check it every time (after loop too)
} continue {
CTK::Daemon::mysleep $step if $step; # Delay! For avoid fast restarts
}
return 1;
}
DESCRIPTION
Abstract class to implement Daemons
FEATURES
Write PID file /var/run/$name.pid to make sure only one instance is running.
Correctly daemonize (redirect STDIN/STDOUT)
Restart by stop/start, exec, or signal HUP
Daemon restart on error
Handle worker processes
Run as different user using setuid/setgid
METHODS
- new
-
my $daemon = new CTK::Daemon('testdaemon', ( ctk => CTK::App->new(...), # Or create CTKx instance first debug => 1, # Default: 0 loglevel => "debug", # Default: undef forks => 3, # Default: 1 uid => "username", # Default: undef gid => "groupname", # Default: undef ));
Daemon constructor
- ctk, get_ctk
-
my $ctk = $daemon->get_ctk;
Returns CTK object
- ctrl
-
exit ctrl( shift @ARGV ); # start, stop, restart, reload, status
LSB Control handler. Dispatching
- logger
-
my $logger = $daemon->logger;
Returns logger object
- logger_close
-
$daemon->logger_close;
Destroy logger
- exit_daemon
-
$self->exit_daemon(0); $self->exit_daemon(1);
Exit with status code
- init, down, run
-
Base methods for overwriting in your class.
The init() method is called at startup - before forking
The run() method is called at inside process and describes body of the your code
The down () method is called at cleanup - after processing
- start, stop, restart, status and hup
-
LSB methods. For internal use only
- exception
-
$exception = $self->exception; $self->exception(exception);
Gets/Sets exception value
- hangup
-
$hangup = $self->hangup; $self->hangup($hangup);
Gets/Sets hangup value
- interrupt
-
$interrupt = $self->interrupt; $self->interrupt($interrupt);
Gets/Sets interrupt value
- skip
-
$skip = $self->skip; $self->skip($skip);
Gets/Sets skip value
- ok
-
sub run { my $self = shift; my $logger = $self->logger; $logger->log_info("Code is running"); my $step = 5; while ($self->ok) { # Check it every time # If occurred usual error: # $logger->log_error("..."); # mysleep SLEEP; # next; # If occurred exception error # $logger->log_crit("..."); # $self->exception(1); # last; # For skip this loop # $self->skip(1); # next; last unless $self->ok; # Check it every time (after loop too) } continue { CTK::Daemon::mysleep $step if $step; # Delay! For avoid fast restarts } return 1; }
Checks worker's state and allows next iteration in main loop
- reinit_worker
-
ReInitialize worker
- worker
-
Internal use only
- mysleep
-
mysleep(5);
Provides safety delay
- myfork
-
my $pid = myfork;
Provides safety forking
EXAMPLE
Classic example:
package My::App;
my $ctk = new CTK::App;
my $daemon = new My::Class('testdaemon', (
ctk => $ctk,
debug => 1,
loglevel => "debug",
forks => 3,
));
my $status = $daemon->ctrl("start");
$daemon->exit_daemon($status);
1;
package My::Class;
use base qw/CTK::Daemon/;
sub new {
my $class = shift;
# ... your code ...
$class->SUPER::new(shift, @_);
}
sub run {
my $self = shift;
my $logger = $self->logger;
$logger->log_info("Code is running");
my $step = 5;
while ($self->ok) { # Check it every time
# If occurred usual error:
# $logger->log_error("...");
# mysleep SLEEP;
# next;
# If occurred exception error
# $logger->log_crit("...");
# $self->exception(1);
# last;
# For skip this loop
# $self->skip(1);
# next;
last unless $self->ok; # Check it every time (after loop too)
} continue {
CTK::Daemon::mysleep $step if $step; # Delay! For avoid fast restarts
}
return 1;
}
1;
AnyEvent example (better):
package My::Class;
use base qw/CTK::Daemon/;
use AnyEvent;
sub run {
my $self = shift;
my $logger = $self->logger;
my $quit_program = AnyEvent->condvar;
# Create watcher timer
my $watcher = AnyEvent->timer (after => 3, interval => 3, cb => sub {
$quit_program->send unless $self->ok;
});
# Create process timer
my $timer = AnyEvent->timer(after => 3, interval => 15, cb => sub {
$quit_program->send unless $self->ok;
$logger->log_info("[%d] Worker is running #%d", $self->{workerident}, $self->{workerpid});
});
# Run!
$quit_program->recv;
return 1;
}
1;
HISTORY
- 1.00 Mon Feb 27 12:33:51 2017 GMT
-
Init version
- 1.01 Mon 13 May 19:53:01 MSK 2019
-
Moved to CTKlib project
See Changes
file
DEPENDENCIES
CTK, POSIX, Sys::Syslog, Try::Tiny
TO DO
See TODO
file
BUGS
* none noted
SEE ALSO
AUTHOR
Serż Minus (Sergey Lepenkov) http://www.serzik.com <abalama@cpan.org>
COPYRIGHT
Copyright (C) 1998-2019 D&D Corporation. All Rights Reserved
Based on PVE::Daemon ideology
LICENSE
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
See LICENSE
file and https://dev.perl.org/licenses