Jede Task-Server-Instanz und jeder Hintergrundjob haben nun ein neues
Attribute »node_id«. Darüber kann gesteuert werden, dass bestimmte
Jobs nur von einer bestimmten Instanz ausgeführt werden.
Die »node_id« eines neu angelegten Jobs ist standardmäßig leer. Das
bedeutet, dass ein Job von einer beliebigen Task-Server-Instanz
ausgeführt werden kann.
Die »node_id« eines Task-Servers ist standardmäßig der Hostname (siehe
ausgabe von »perl -MSys::Hostname -le 'print hostname()'«), kann aber
in der Konfigurationsdatei überschrieben werden (»[task_server]« →
»node_id«).
Zusätzlich gibt es den Konfigurationsparameter »[task_server]« →
»only_run_tasks_for_this_node«. Ist dieser Parameter gesetzt, so führt
der Task-Server nur diejenigen Jobs aus, deren »node_id«-Feld mit der
»node_id« der Task-Server-Instanz übereinstimmt. Andernfalls werden
auch diejenigen Jobs ausgeführt, deren »node_id«-Feld leer ist.
Achtung: es findet momentan keinerlei Locking statt. Das bedeutet,
dass es für jede Datenbank nur eine Task-Server-Instanz geben darf,
bei der »only_run_tasks_for_this_node« nicht gesetzt ist. Für
Load-Balancing eignet sich das also bisher noch nicht.
use parent qw(SL::BackgroundJob::Base);
use parent qw(SL::BackgroundJob::Base);
+use SL::System::TaskServer;
+
sub run {
my ($self, $db_obj) = @_;
my $data = $db_obj->data_as_hash;
sub run {
my ($self, $db_obj) = @_;
my $data = $db_obj->data_as_hash;
- $::lxdebug->message(0, "Test job is being executed.");
+ $::lxdebug->message(0, "Test job ID " . $db_obj->id . " is being executed on node " . SL::System::TaskServer::node_id() . ".");
die "Oh cruel world: " . $data->{exception} if $data->{exception};
die "Oh cruel world: " . $data->{exception} if $data->{exception};
use SL::DB::Helper::Paginated;
use SL::DB::Helper::Sorted;
use SL::DB::Helper::Paginated;
use SL::DB::Helper::Sorted;
+use SL::System::TaskServer;
+
sub object_class { 'SL::DB::BackgroundJob' }
__PACKAGE__->make_manager_methods;
sub object_class { 'SL::DB::BackgroundJob' }
__PACKAGE__->make_manager_methods;
cron_spec => '',
next_run_at => undef,
next_run_at => { le => $now } ] ]);
cron_spec => '',
next_run_at => undef,
next_run_at => { le => $now } ] ]);
-
- return $class->get_all(query => [ or => [ @interval_args, @once_args ] ]);
+ my @node_filter;
+
+ my $node_id = SL::System::TaskServer->node_id;
+ if ($::lx_office_conf{task_server}->{only_run_tasks_for_this_node}) {
+ @node_filter = (node_id => $node_id);
+ } else {
+ @node_filter = (
+ or => [
+ node_id => undef,
+ node_id => '',
+ node_id => $node_id,
+ ]);
+ }
+
+ return $class->get_all(query => [ or => [ @interval_args, @once_args ], @node_filter ]);
id => { type => 'serial', not_null => 1 },
last_run_at => { type => 'timestamp' },
next_run_at => { type => 'timestamp' },
id => { type => 'serial', not_null => 1 },
last_run_at => { type => 'timestamp' },
next_run_at => { type => 'timestamp' },
+ node_id => { type => 'text' },
package_name => { type => 'varchar', length => 255 },
type => { type => 'varchar', length => 255 },
);
package_name => { type => 'varchar', length => 255 },
type => { type => 'varchar', length => 255 },
);
use File::Slurp;
use File::Spec::Functions qw(:ALL);
use File::Temp;
use File::Slurp;
use File::Spec::Functions qw(:ALL);
use File::Temp;
use constant PID_BASE => "users/pid";
use constant PID_BASE => "users/pid";
sub status {
my ($self) = @_;
sub status {
my ($self) = @_;
return kill('ALRM', $pid) ? 1 : undef;
}
return kill('ALRM', $pid) ? 1 : undef;
}
+sub node_id {
+ return $node_id if $node_id;
+
+ $node_id = ($::lx_office_conf{task_server} // {})->{node_id} || Sys::Hostname::hostname();
+
+ return $node_id;
+}
+
debug = 0
# Chose a system user the daemon should run under when started as root.
run_as =
debug = 0
# Chose a system user the daemon should run under when started as root.
run_as =
+# Task servers can run on multiple machines. Each needs its own unique
+# ID. If unset, it defaults to the host name. All but one task server
+# must have 'only_run_tasks_for_this_node' set to 1.
+node_id =
+only_run_tasks_for_this_node = 0
[task_server/notify_on_failure]
# If you want email notifications for failed jobs then set this to a
[task_server/notify_on_failure]
# If you want email notifications for failed jobs then set this to a
run_single_job_for_all_clients();
return;
}
run_single_job_for_all_clients();
return;
}
+ $::lxdebug->message(LXDebug::INFO(), "The task server for node " . SL::System::TaskServer::node_id() . " is up and running.");
while (1) {
$SIG{'ALRM'} = 'IGNORE';
while (1) {
$SIG{'ALRM'} = 'IGNORE';
--- /dev/null
+-- @tag: add_node_id_to_background_jobs
+-- @description: Spalte 'node_id' in 'background_jobs'
+-- @depends: release_3_5_4
+ALTER TABLE background_jobs
+ADD COLUMN node_id TEXT;