App-MonM
view release on metacpan or search on metacpan
lib/App/MonM/Daemon.pm view on Meta::CPAN
}
sub reload {
my $self = shift;
my $logger = $self->logger;
# Check configuration
my $configobj = $self->ctk->configobj;
unless ($configobj->reload->status) {
print STDERR length($configobj->error)
? $configobj->error
: "Can't reload configuration file";
return $self->interrupt(1);
}
#$logger->log_info(">> Reload handler");
return 1;
}
sub run {
my $self = shift;
my $ctk = $self->get_ctk;
my $logger = $self->logger;
my $quit_program = AnyEvent->condvar;
return 1 unless $self->ok;
#$logger->log_info(">> Run handler");
# CTK config
my $config = $ctk->config;
# Get checkits and allocation by workers
my @checkits = getCheckitByName($ctk->config("checkit"));
my $noc = scalar(@checkits);
unless ($noc) {
$logger->log_error("No enabled <Checkit> configuration section found");
return 0;
}
my @checkits_parted = (_allocate($self->{forkers}, [(sort {$a->{name} cmp $b->{name}} @checkits)]));
my $alloc = $checkits_parted[$self->{workerident} - 1];
# Store
my $db_file = File::Spec->catfile($ctk->datadir, App::MonM::Store::DB_FILENAME());
my $store_conf = $ctk->config("store") || $ctk->config('dbi') || {file => $db_file};
$store_conf = {file => $db_file} unless is_hash($store_conf);
my %store_args = %$store_conf;
$store_args{file} = $db_file unless ($store_args{file} || $store_args{dsn});
my $store = App::MonM::Store->new(%store_args);
if ($store->error) {
$logger->log_error($store->error);
return 0;
}
$self->{store} = $store;
# Notifier object init
my %nargs = (config => $ctk->configobj);
$self->{notifier} = $NOTIFIER_LOADED && lvalue($ctk->config("usemonotifier"))
? App::MonM::Notifier->new(%nargs)
: App::MonM::QNotifier->new(%nargs);
# Create Checkit object
$self->{checker} = App::MonM::Checkit->new;
# Create process timers
my $ctrl = AnyEvent->timer (after => START_DELAY, interval => INTERVAL_CTRL, cb => sub {
$quit_program->send(1) unless $self->ok;
});
my $interval = int(uv2zero(lvalue($ctk->config("interval"))) || INTERVAL_MAIN); # Time interval. 1 op per n sec
my $after = (($self->{workerident} - 1) * int($interval / ($self->{forkers} - 1))) || START_DELAY;
my $timer = AnyEvent->timer (after => $after, interval => $interval, cb => sub {
$quit_program->send(1) unless $self->ok;
$self->slave($alloc); # Go!
});
my $rmnd = AnyEvent->timer (after => INTERVAL_REMIND+START_DELAY, interval => INTERVAL_REMIND, cb => sub {
$quit_program->send(1) unless $self->ok;
$self->remind() if $self->{workerident} == 1;
});
# Run!
$quit_program->recv;
return 1;
}
sub remind {
my $self = shift;
return $self->logger->log_error(($self->notifier->error)) unless $self->notifier->remind;
return 1;
}
sub slave {
my $self = shift;
my $checkits = shift;
my $ctk = $self->get_ctk;
my $logger = $self->logger;
my $worker = $self->{workerident};
my $store = $self->store;
#$logger->log_info(">> $$ worker=%d", $worker);
# Check checkits
return 1 unless $checkits && is_array($checkits) && isnt_void($checkits);
# Get Checker object
my $checker = $self->checker;
# Get all records from DB
my %all;
foreach my $r ($store->getall) { $all{$r->{name}} = $r }
if ($store->error) {
$logger->log_error($store->error);
return 1;
}
# Start
my $curtime = time;
foreach my $checkit (@$checkits) {
my $result = 1; # Check result
my $name = $checkit->{name}; # checkit name
my $info = $all{$name} || {}; # data from database
my $id = $info->{id} || 0;
my $old = $info->{status} || 0;
my $got = ($old << 1) & 15;
my $pub = $info->{'time'} || 0;
my $interval = getTimeOffset(lvalue($checkit, "interval") || 0);
# Check interval first
if ($interval) {
if (($pub + $interval) >= $curtime) {
$logger->log_debug("SKIP %s (%s)\n", $name,
"Too little time has passed before a next check [delay $interval sec]")
if $ctk->verbosemode;
next;
}
}
# Check!
( run in 0.689 second using v1.01-cache-2.11-cpan-bbcb1afb8fc )