add scheduler based on Algorithm::Cron
This commit is contained in:
@@ -4,6 +4,7 @@ name 'App-Netdisco';
|
||||
license 'bsd';
|
||||
all_from 'lib/App/Netdisco.pm';
|
||||
|
||||
requires 'Algorithm::Cron' => 0;
|
||||
requires 'App::cpanminus' => 0;
|
||||
requires 'App::local::lib::helper' => 0;
|
||||
requires 'DBD::Pg' => 0;
|
||||
|
||||
@@ -46,6 +46,8 @@ sub build_tasks_list {
|
||||
user_begin => worker_factory('Manager'),
|
||||
}];
|
||||
|
||||
set(daemon_schedulers => 1)
|
||||
if !defined setting('daemon_schedulers');
|
||||
set(daemon_pollers => 2)
|
||||
if !defined setting('daemon_pollers');
|
||||
set(daemon_interactives => 2)
|
||||
@@ -53,6 +55,11 @@ sub build_tasks_list {
|
||||
|
||||
# XXX MCE does not like max_workers => 0
|
||||
|
||||
push @$tasks, {
|
||||
max_workers => setting('daemon_schedulers'),
|
||||
user_begin => worker_factory('Scheduler'),
|
||||
} if setting('daemon_schedulers');
|
||||
|
||||
push @$tasks, {
|
||||
max_workers => setting('daemon_pollers'),
|
||||
user_begin => worker_factory('Poller'),
|
||||
@@ -63,8 +70,11 @@ sub build_tasks_list {
|
||||
user_begin => worker_factory('Interactive'),
|
||||
} if setting('daemon_interactives');
|
||||
|
||||
info sprintf "MCE will load %s tasks: 1 Manager, %s Poller, %s Interactive",
|
||||
(1+ scalar @$tasks), (setting('daemon_pollers') || 0), (setting('daemon_interactives') || 0);
|
||||
info sprintf "MCE will load %s tasks: 1 Manager, %s Scheduler, %s Poller, %s Interactive",
|
||||
(1+ scalar @$tasks),
|
||||
(setting('daemon_schedulers') || 0),
|
||||
(setting('daemon_pollers') || 0),
|
||||
(setting('daemon_interactives') || 0);
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
|
||||
79
Netdisco/lib/App/Netdisco/Daemon/Worker/Scheduler.pm
Normal file
79
Netdisco/lib/App/Netdisco/Daemon/Worker/Scheduler.pm
Normal file
@@ -0,0 +1,79 @@
|
||||
package App::Netdisco::Daemon::Worker::Scheduler;
|
||||
|
||||
use Dancer qw/:moose :syntax :script/;
|
||||
use Dancer::Plugin::DBIC 'schema';
|
||||
|
||||
use Algorithm::Cron;
|
||||
use Try::Tiny;
|
||||
|
||||
use Role::Tiny;
|
||||
use namespace::clean;
|
||||
|
||||
my $jobactions = {
|
||||
map {$_ => undef} qw/
|
||||
discoverall
|
||||
refresh
|
||||
macwalk
|
||||
arpwalk
|
||||
nbtwalk
|
||||
backup
|
||||
/
|
||||
};
|
||||
|
||||
sub worker_begin {
|
||||
my $self = shift;
|
||||
my $wid = $self->wid;
|
||||
debug "entering Scheduler ($wid) worker_begin()";
|
||||
|
||||
foreach my $a (keys %$jobactions) {
|
||||
next unless setting('job_schedule')
|
||||
and exists setting('job_schedule')->{$a};
|
||||
my $config = setting('job_schedule')->{$a};
|
||||
|
||||
# accept either single crontab format, or individual time fields
|
||||
my $cron = Algorithm::Cron->new(@{
|
||||
ref [] eq ref $config->{when}
|
||||
? $config->{when}
|
||||
: [crontab => $config->{when}];
|
||||
});
|
||||
|
||||
$jobactions->{$a} = $config;
|
||||
$jobactions->{$a}->{when} = $cron;
|
||||
}
|
||||
}
|
||||
|
||||
sub worker_body {
|
||||
my $self = shift;
|
||||
my $wid = $self->wid;
|
||||
|
||||
while (1) {
|
||||
# sleep until some point in the next minute
|
||||
my $naptime = 60 - (time % 60) + int(rand(45));
|
||||
debug "scheduler ($wid): sleeping for $naptime seconds";
|
||||
sleep $naptime;
|
||||
|
||||
my $win_start = time - (time % 60);
|
||||
my $win_end = $win_start + 60;
|
||||
|
||||
# if any job is due, add it to the queue
|
||||
foreach my $a (keys %$jobactions) {
|
||||
next unless defined $jobactions->{$a};
|
||||
my $sched = $jobactions->{$a};
|
||||
|
||||
if ($sched->{when}->next_time($win_start) < $win_end) {
|
||||
# queue it!
|
||||
try {
|
||||
debug "scheduler ($wid): queueing $a job";
|
||||
schema('netdisco')->resultset('Admin')->create({
|
||||
action => $a,
|
||||
device => ($sched->{device} || undef),
|
||||
subaction => ($sched->{extra} || undef),
|
||||
status => 'queued',
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -72,6 +72,7 @@ daemon_sleep_time: 5
|
||||
|
||||
# how many daemon processes
|
||||
# NB one worker will always be a Queue Manager
|
||||
daemon_pollers: 0
|
||||
daemon_schedulers: 1
|
||||
daemon_interactives: 2
|
||||
daemon_pollers: 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user