use System::Introspector::Logger qw( :log :dlog );
has introspectors => (is => 'ro', required => 1);
+has stderr_fh => ( is => 'ro' );
sub gather_all {
my ($self) = @_;
log_debug { "Using '$module' for this gather" };
my $module_name = use_module($module);
log_trace { "Finished loading '$module'; returned value was '$module_name'" };
- my $instance = $module_name->new::on('-', $args);
- #my $instance = $module_name->new($args);
+ #my $instance = $module_name->new::on('-', $args);
+ my $instance = $module_name->new($args);
log_trace { "Finished constructing '$module_name'; starting gather" };
my $probe_data = $instance->gather;
log_trace { "Gathering completed, storing data in the report for '$module_name'" };
my ($user, $host, $sudo_user) = @arg{qw( user host sudo_user )};
my $sudo = defined($sudo_user) ? sprintf('%s@', $sudo_user) : undef;
my $args = { introspectors => $arg{introspectors} };
+ #TODO move watchdog_timeout into an attribute for this class
+ my %connection_args = ( stderr => $arg{stderr_fh}, watchdog_timeout => 300 );
if (defined $host) {
my $remote = join '@', grep defined, $user, $host;
- my $conn = Object::Remote::Connection->conn_from_spec($remote, watchdog_timeout => 120);
+ my $conn = Object::Remote::Connection->conn_from_spec($remote, %connection_args);
$conn->maybe::start::connect;
if (defined $sudo_user) {
return $class->_new_bridged($conn->maybe::start::connect, $sudo, $args);
else {
if (defined $sudo_user) {
#TODO find a better way to achieve this result
- my $conn = Object::Remote::Connection->conn_from_spec($sudo_user, watchdog_timeout => 120);
+ my $conn = Object::Remote::Connection->conn_from_spec($sudo_user, %connection_args);
return $class->_new_direct($conn->maybe::start::connect, $args);
}
}
}
+#let the controller shut down this process on command
+sub quit {
+ my ($self) = @_;
+ log_debug { "this gatherer got a quit command, invoking exit(0)" };
+ exit(0);
+}
+
1;
__END__
my ($self, @groups) = @_;
log_debug { "Starting to gather results" };
for my $group (@groups) {
- my @waiting;
- for my $host ($self->config->hosts) {
- log_debug { "Adding group '$group' on '$host' to list of active fetches" };
- push @waiting, [$host, $self->fetch($host, $group)];
- }
- log_debug { sprintf("There are %i hosts in the waiting list", scalar(@waiting)) };
- for my $wait (@waiting) {
- my ($host, @futures) = @$wait;
- my $report;
-
- log_debug { "Waiting on futures for host '$host'" };
-
- #TODO another way to solve the huge JSON problem is to
- #invoke the probes in from controller directly via proxy
- #objects and receive the results from each probe as
- #they complete - it would cause less RAM consumption for the
- #system as a whole but requires modifying the future based
- #syncronization logic
- eval { ($report) = await_all @futures };
+ my @hosts = $self->config->hosts;
+
+ log_info { my $c = scalar(@hosts); "This gather run is for $c hosts" };
+
+ while(scalar(@hosts) > 0) {
+ #TODO turn the splice size into an attribute on this class
+ my @scan = splice(@hosts, 0, 50);
+ my @waiting;
+
+ Dlog_trace { my $c = scalar(@scan); "Scanning $c hosts in this gather loop" } @scan;
- if ($@) {
- log_error { "Failure when probing '$host': $@" };
- next;
+ for my $host (@scan) {
+ log_debug { "Adding group '$group' on '$host' to list of active fetches" };
+ my $to_fetch;
+
+ eval { $to_fetch = [$host, $self->fetch($host, $group)] };
+
+ if ($@) {
+ log_trace { "Could not start fetching for $host: '$@'" };
+ next;
+ }
+
+ push @waiting, $to_fetch;
}
-
- log_trace { "Received all from group '$group' on '$host'" };
- $self->_store($host, $group, $report);
- }
- }
+ log_debug { sprintf("There are %i hosts in the waiting list", scalar(@waiting)) };
+ for my $wait (@waiting) {
+ my ($host, @futures) = @$wait;
+ my $report;
+
+ log_debug { "Waiting on futures for host '$host'" };
+
+ #TODO another way to solve the huge JSON problem is to
+ #invoke the probes in from controller directly via proxy
+ #objects and receive the results from each probe as
+ #they complete - it would cause less RAM consumption for the
+ #system as a whole but requires modifying the future based
+ #syncronization logic
+ eval { ($report) = await_all @futures };
+
+ if ($@) {
+ log_error { "Failure when probing '$host': $@" };
+ next;
+ }
+
+ log_trace { "Received all from group '$group' on '$host'" };
+ $self->_store($host, $group, $report);
+ }
+ }
+ }
+
log_debug { "Completed gathering results" };
return 1;
}
my $storage = $self->storage($host, $group);
my $ok = eval {
my @files;
-# for my $class (sort keys %$gathered) {
for my $class ($gathered->probe_names) {
log_trace { "Storing data for probe name '$class'" };
my $file = sprintf '%s.json', join '/',
sub _create_gatherer {
my ($self, %arg) = @_;
+ my $stderr_fh;
+
+ #TODO move into attribute for this class
+if(1) {
+ my $log_file = "log/$arg{host}.log";
+
+ log_debug { "Logging stderr for host '$arg{host}' to '$log_file'" };
+
+ open($stderr_fh, ">>", $log_file) or die "Could not open '$log_file' for write: $!";
+
+}
+
my $gatherer = System::Introspector::Gatherer->new_from_spec(
user => $self->user,
+ stderr_fh => $stderr_fh,
host => $arg{host},
sudo_user => $arg{sudo} && $self->sudo_user,
introspectors => $arg{introspectors},
);
my $future = $gatherer->start::gather_all;
-
- $self->_create_watchdog($gatherer, $future);
-
+
return $future;
}
-sub _create_watchdog {
- my ($self, $gatherer, $future) = @_;
- my $timeout = 3;
-# my $handler = $self->_create_watchdog_handler($timeout, $gatherer, $future);
-#
-# $self->_schedule_watchdog( $handler, $timeout );
-}
-
-sub _schedule_watchdog {
- my ($self, $handler, $timeout) = @_;
- my $timer_id;
-
- log_trace { "Setting a watchdog to check a gatherer after $timeout seconds" };
-
- $timer_id = Object::Remote->current_loop->watch_time(
- every => $timeout,
- code => sub {
- log_trace { "Watchdog timer has expired; checking on gatherer" };
- unless ($handler->()) {
- log_trace { "Not scheduling watchdog to execute again" };
- $handler = undef;
- Object::Remote->current_loop->unwatch_time($timer_id);
- }
- }
- );
-}
-
-sub _create_watchdog_handler {
- my ($self, $timeout, $gatherer, $future) = @_;
-
- return sub {
- #handler returns 1 if it should run again or 0 otherwise
- my $ping_waiting;
-
- log_debug { "Watchdog is checking up on gatherer" };
-
- if ($future->is_ready || $future->is_cancelled) {
- log_trace { "Future for gatherer is ready or cancelled; watchdog is no longer needed" };
- return 0;
- }
-
- if ($ping_waiting) {
- log_debug { "This gatherer did not respond to a ping after '$timeout' seconds" };
- $future->fail("Gatherer did not respond to ping");
- return 0;
- }
-
- log_trace { "Watchdog is going to ping the gatherer" };
-
- $ping_waiting = 1;
- my $ping_resp;
- eval { $ping_resp = $gatherer->ping };
-
- log_trace { "Ping completed" };
-
- if ($@) {
- log_debug { "Could not invoke ping method on gatherer: $@" };
- $future->fail("Could not ping gatherer: $@") unless $future->is_ready;
- return 0;
- } else {
- log_debug { "Ping to gatherer did not return true" };
- $future->fail("Ping to gatherer did not return true") unless $future->is_ready;
- }
-
- $ping_waiting = 0;
-
- log_trace { "The watchdog did not find any problems" };
-
- return 1;
- }
-}
-
1;
=head1 NAME