diff --git a/Netdisco/lib/App/Netdisco/Daemon/Queue.pm b/Netdisco/lib/App/Netdisco/Daemon/Queue.pm index 056a9c48..7a354cd0 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Queue.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Queue.pm @@ -33,11 +33,13 @@ sub capacity_for { debug "checking local capacity for action $action"; my $action_map = { - Interactive => [qw/location contact portcontrol portname vlan power/] + Poller => [qw//], + Interactive => [qw/location contact portcontrol portname vlan power/], }; my $role_map = { - map {$_ => 'Interactive'} @{ $action_map->{Interactive} } + (map {$_ => 'Poller'} @{ $action_map->{Poller} }), + (map {$_ => 'Interactive'} @{ $action_map->{Interactive} }) }; my $setting_map = { diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm index abd8ac8a..0842ec65 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm @@ -13,8 +13,10 @@ use namespace::clean; my $fqdn = hostfqdn || 'localhost'; my $role_map = { - map {$_ => 'Interactive'} - qw/location contact portcontrol portname vlan power/ + (map {$_ => 'Poller'} + qw//), + (map {$_ => 'Interactive'} + qw/location contact portcontrol portname vlan power/) }; sub worker_begin { diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Poller.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Poller.pm new file mode 100644 index 00000000..3ca0c592 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Poller.pm @@ -0,0 +1,73 @@ +package App::Netdisco::Daemon::Worker::Poller; + +use Dancer qw/:moose :syntax :script/; +use Dancer::Plugin::DBIC 'schema'; +use Try::Tiny; + +use Role::Tiny; +use namespace::clean; + +# add dispatch methods for poller tasks +with 'App::Netdisco::Daemon::Worker::Poller::Discover'; + +sub worker_body { + my $self = shift; + my $wid = $self->wid; + + while (1) { + debug "poll ($wid): asking for a job"; + my $jobs = $self->do('take_jobs', $self->wid, 'Poller'); + + foreach my $candidate (@$jobs) { + # create a row object so we can use column accessors + # use the local db schema in case it is accidentally 'stored' + # (will throw an exception) + my $job = schema('daemon')->resultset('Admin') + ->new_result($candidate); + my $jid = $job->job; + + my $target = 'set_'. $job->action; + next unless $self->can($target); + debug "poll ($wid): can ${target}() for job $jid"; + + # do job + my ($status, $log); + try { + $job->started(scalar localtime); + info sprintf "poll (%s): starting job %s at %s", $wid, $jid, $job->started; + ($status, $log) = $self->$target($job); + } + catch { + $status = 'error'; + $log = "error running job: $_"; + $self->sendto('stderr', $log ."\n"); + }; + + $self->close_job($job, $status, $log); + } + + debug "poll ($wid): sleeping now..."; + sleep( setting('daemon_sleep_time') || 5 ); + } +} + +sub close_job { + my ($self, $job, $status, $log) = @_; + my $now = scalar localtime; + info sprintf "poll (%s): wrapping up job %s - status %s at %s", + $self->wid, $job->job, $status, $now; + + try { + schema('netdisco')->resultset('Admin') + ->find($job->job) + ->update({ + status => $status, + log => $log, + started => $job->started, + finished => $now, + }); + } + catch { $self->sendto('stderr', "error closing job: $_\n") }; +} + +1;