Skip to content

Commit

Permalink
fork before loading tasks code in server mode
Browse files Browse the repository at this point in the history
This avoid cluttering main process memory uselessly.
  • Loading branch information
Guillaume Rousse authored and Guillaume Rousse committed Mar 19, 2012
1 parent fa04fe1 commit 050c20a
Showing 1 changed file with 79 additions and 48 deletions.
127 changes: 79 additions & 48 deletions lib/FusionInventory/Agent.pm
Expand Up @@ -255,25 +255,10 @@ sub _runTarget {
sub _runTask {
my ($self, $target, $name, $response) = @_;

my $class = "FusionInventory::Agent::Task::$name";
my $task = $class->new(
config => $self->{config},
confdir => $self->{confdir},
datadir => $self->{datadir},
logger => $self->{logger},
target => $target,
deviceid => $self->{deviceid},
);

if (!$task->isEnabled($response)) {
$self->{logger}->info("task $name is not enabled");
return;
}

$self->{status} = "running task $name";

if ($self->{config}->{daemon} || $self->{config}->{service}) {
# daemon mode: run each task in a child process
# server mode: run each task in a child process
if (my $pid = fork()) {
# parent
waitpid($pid, 0);
Expand All @@ -282,28 +267,45 @@ sub _runTask {
die "fork failed: $ERRNO" unless defined $pid;

$self->{logger}->debug("running task $name in process $PID");
$task->run(
user => $self->{config}->{user},
password => $self->{config}->{password},
proxy => $self->{config}->{proxy},
ca_cert_file => $self->{config}->{'ca-cert-file'},
ca_cert_dir => $self->{config}->{'ca-cert-dir'},
no_ssl_check => $self->{config}->{'no-ssl-check'},
);
$self->_runTaskReal($target, $name, $response);
exit(0);
}
} else {
# standalone mode: run each task directly
$self->{logger}->debug("running task $name");
$task->run(
user => $self->{config}->{user},
password => $self->{config}->{password},
proxy => $self->{config}->{proxy},
ca_cert_file => $self->{config}->{'ca-cert-file'},
ca_cert_dir => $self->{config}->{'ca-cert-dir'},
no_ssl_check => $self->{config}->{'no-ssl-check'},
);
$self->_runTaskReal($target, $name, $response);
}
}

sub _runTaskReal {
my ($self, $target, $name, $response) = @_;

my $class = "FusionInventory::Agent::Task::$name";

$class->require();

my $task = $class->new(
config => $self->{config},
confdir => $self->{confdir},
datadir => $self->{datadir},
logger => $self->{logger},
target => $target,
deviceid => $self->{deviceid},
);

if (!$task->isEnabled($response)) {
$self->{logger}->info("task $name is not enabled");
return;
}

$task->run(
user => $self->{config}->{user},
password => $self->{config}->{password},
proxy => $self->{config}->{proxy},
ca_cert_file => $self->{config}->{'ca-cert-file'},
ca_cert_dir => $self->{config}->{'ca-cert-dir'},
no_ssl_check => $self->{config}->{'no-ssl-check'},
);
}

sub getToken {
Expand All @@ -324,7 +326,6 @@ sub getStatus {
sub getAvailableTasks {
my ($self, %params) = @_;

my $logger = $self->{logger};
my %tasks;
my %disabled = map { lc($_) => 1 } @{$params{disabledTasks}};

Expand All @@ -340,30 +341,60 @@ sub getAvailableTasks {

next if $disabled{lc($name)};

# check module
# todo: use a child process when running as a server to save memory
if (!$module->require()) {
$logger->debug2("module $module does not compile") if $logger;
next;
}
if (!$module->isa('FusionInventory::Agent::Task')) {
$logger->debug2("module $module is not a task") if $logger;
next;
}

# retrieve version
my $version;
{
no strict 'refs'; ## no critic
$version = ${$module . '::VERSION'};
if ($self->{config}->{daemon} || $self->{config}->{service}) {
# server mode: check each task version in a child process
my $pid = open(my $handle, '-|');
die "fork failed: $ERRNO" unless defined $pid;

if ($pid) {
# parent
$version = <$handle>;
close $handle;
} else {
# child
$version = $self->_getTaskVersion($module);
print $version if $version;
exit(0);
}
} else {
# standalone mode: check each task version directly
$version = $self->_getTaskVersion($module);
}

# no version means non-functionning task
next unless $version;

$tasks{$name} = $version;
}

return %tasks;
}

sub _getTaskVersion {
my ($self, $module) = @_;

my $logger = $self->{logger};

if (!$module->require()) {
$logger->debug2("module $module does not compile") if $logger;
return;
}

if (!$module->isa('FusionInventory::Agent::Task')) {
$logger->debug2("module $module is not a task") if $logger;
return;
}

my $version;
{
no strict 'refs'; ## no critic
$version = ${$module . '::VERSION'};
}

return $version;
}

sub _isAlreadyRunning {
my ($self) = @_;

Expand Down

0 comments on commit 050c20a

Please sign in to comment.