1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#
# (c) Jan Gehring <jan.gehring@gmail.com>
#
package Rex::TaskList::Parallel_ForkManager;
use v5.12.5;
use warnings;
our $VERSION = '1.14.1'; # VERSION
use Data::Dumper;
use Rex::Logger;
use Rex::Task;
use Rex::Config;
use Rex::Interface::Executor;
use Rex::TaskList::Base;
use Rex::Report;
use Time::HiRes qw(time);
BEGIN {
use Rex::Require;
Parallel::ForkManager->require;
}
use base qw(Rex::TaskList::Base);
sub run {
my ( $self, $task, %options ) = @_;
if ( !ref $task ) {
$task = Rex::TaskList->create()->get_task($task);
}
my $fm = Parallel::ForkManager->new( $self->get_thread_count($task) );
$fm->set_waitpid_blocking_sleep(
Rex::Config->get_waitpid_blocking_sleep_time );
my $all_servers = $task->server;
$fm->run_on_finish(
sub {
my ( $pid, $exit_code ) = @_;
Rex::Logger::debug("Fork exited: $pid -> $exit_code");
}
);
for my $server (@$all_servers) {
my $child_coderef = $self->build_child_coderef( $task, $server, %options );
if ( $self->{IN_TRANSACTION} ) {
# Inside a transaction -- no forking and no chance to get zombies.
# This only happens if someone calls do_task() from inside a transaction.
$child_coderef->();
}
else {
# Not inside a transaction, so lets fork
$fm->start and next;
$child_coderef->();
$fm->finish;
}
}
Rex::Logger::debug("Waiting for children to finish");
my $ret = $fm->wait_all_children;
Rex::reconnect_lost_connections();
return $ret;
}
1;
|