#!/usr/bin/env perl use FindBin; use lib "$FindBin::Bin/../lib"; use App::Netdisco; # for netdisco app config use Dancer qw/:moose :script/; # callbacks and local job queue management use App::Netdisco::Daemon::Queue ':all'; # needed to quench AF_INET6 symbol errors use NetAddr::IP::Lite ':lower'; use MCE; use Role::Tiny::With; use Path::Class 'dir'; my $tmp = dir($ENV{HOME}, 'tmp'); mkdir $tmp if ! -d $tmp; my $mce = MCE->new( tmp_dir => $tmp, spawn_delay => 0.15, job_delay => 0.15, user_func => sub { $_[0]->worker_body }, on_post_exit => \&restart_worker, user_tasks => build_tasks_list(), )->run(); sub build_tasks_list { my $tasks = [{ max_workers => 1, user_begin => worker_factory('Manager'), }]; set(daemon_pollers => 2) if !defined setting('daemon_pollers'); set(daemon_interactives => 2) if !defined setting('daemon_interactives'); # XXX MCE does not like max_workers => 0 push @$tasks, { max_workers => setting('daemon_pollers'), user_begin => worker_factory('Poller'), } if setting('daemon_pollers'); push @$tasks, { max_workers => setting('daemon_interactives'), user_begin => worker_factory('Interactive'), } if setting('daemon_interactives'); return $tasks; } sub worker_factory { my $role = shift; return sub { my $self = shift; Role::Tiny->apply_roles_to_object($self, "App::Netdisco::Daemon::Worker::$role"); # XXX temporary hack to work around MCE's use of __DIE__ my $mce_die = $SIG{__DIE__}; $SIG{__DIE__} = sub { return @_ if $^S and $^S eq 1; $mce_die->(@_) }; # XXX "there's nothing so permanent as temporary..." ~~ Milton Friedman $self->worker_begin if $self->can('worker_begin'); }; } sub restart_worker { my ($self, $e) = @_; reset_jobs($e->{wid}); $self->restart_worker($e->{wid}); }