CTK::Daemon - Abstract class to implement Daemons
Version 1.04
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; }
Abstract class to implement Daemons
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
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
my $ctk = $daemon->get_ctk;
Returns CTK object
exit ctrl( shift @ARGV ); # start, stop, restart, reload, status
LSB Control handler. Dispatching
my $logger = $daemon->logger;
Returns logger object
$daemon->logger_close;
Destroy logger
$self->exit_daemon(0); $self->exit_daemon(1);
Exit with status code
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
LSB methods. For internal use only
$exception = $self->exception; $self->exception(exception);
Gets/Sets exception value
$hangup = $self->hangup; $self->hangup($hangup);
Gets/Sets hangup value
$interrupt = $self->interrupt; $self->interrupt($interrupt);
Gets/Sets interrupt value
$skip = $self->skip; $self->skip($skip);
Gets/Sets skip value
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
ReInitialize worker
Internal use only
mysleep(5);
Provides safety delay
my $pid = myfork;
Provides safety forking
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;
Init version
Moved to CTKlib project
See Changes file
Changes
CTK, POSIX, Sys::Syslog, Try::Tiny
See TODO file
TODO
* none noted
CTK, POSIX
Serż Minus (Sergey Lepenkov) http://www.serzik.com <abalama@cpan.org>
Copyright (C) 1998-2019 D&D Corporation. All Rights Reserved
Based on PVE::Daemon ideology
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
LICENSE
To install CTK, copy and paste the appropriate command in to your terminal.
cpanm
cpanm CTK
CPAN shell
perl -MCPAN -e shell install CTK
For more information on module installation, please visit the detailed CPAN module installation guide.