add scheduler based on Algorithm::Cron
This commit is contained in:
@@ -4,6 +4,7 @@ name 'App-Netdisco';
|
|||||||
license 'bsd';
|
license 'bsd';
|
||||||
all_from 'lib/App/Netdisco.pm';
|
all_from 'lib/App/Netdisco.pm';
|
||||||
|
|
||||||
|
requires 'Algorithm::Cron' => 0;
|
||||||
requires 'App::cpanminus' => 0;
|
requires 'App::cpanminus' => 0;
|
||||||
requires 'App::local::lib::helper' => 0;
|
requires 'App::local::lib::helper' => 0;
|
||||||
requires 'DBD::Pg' => 0;
|
requires 'DBD::Pg' => 0;
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ sub build_tasks_list {
|
|||||||
user_begin => worker_factory('Manager'),
|
user_begin => worker_factory('Manager'),
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
set(daemon_schedulers => 1)
|
||||||
|
if !defined setting('daemon_schedulers');
|
||||||
set(daemon_pollers => 2)
|
set(daemon_pollers => 2)
|
||||||
if !defined setting('daemon_pollers');
|
if !defined setting('daemon_pollers');
|
||||||
set(daemon_interactives => 2)
|
set(daemon_interactives => 2)
|
||||||
@@ -53,6 +55,11 @@ sub build_tasks_list {
|
|||||||
|
|
||||||
# XXX MCE does not like max_workers => 0
|
# 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, {
|
push @$tasks, {
|
||||||
max_workers => setting('daemon_pollers'),
|
max_workers => setting('daemon_pollers'),
|
||||||
user_begin => worker_factory('Poller'),
|
user_begin => worker_factory('Poller'),
|
||||||
@@ -63,8 +70,11 @@ sub build_tasks_list {
|
|||||||
user_begin => worker_factory('Interactive'),
|
user_begin => worker_factory('Interactive'),
|
||||||
} if setting('daemon_interactives');
|
} if setting('daemon_interactives');
|
||||||
|
|
||||||
info sprintf "MCE will load %s tasks: 1 Manager, %s Poller, %s Interactive",
|
info sprintf "MCE will load %s tasks: 1 Manager, %s Scheduler, %s Poller, %s Interactive",
|
||||||
(1+ scalar @$tasks), (setting('daemon_pollers') || 0), (setting('daemon_interactives') || 0);
|
(1+ scalar @$tasks),
|
||||||
|
(setting('daemon_schedulers') || 0),
|
||||||
|
(setting('daemon_pollers') || 0),
|
||||||
|
(setting('daemon_interactives') || 0);
|
||||||
return $tasks;
|
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
|
# how many daemon processes
|
||||||
# NB one worker will always be a Queue Manager
|
# NB one worker will always be a Queue Manager
|
||||||
daemon_pollers: 0
|
daemon_schedulers: 1
|
||||||
daemon_interactives: 2
|
daemon_interactives: 2
|
||||||
|
daemon_pollers: 0
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user