forked from dginev/deprecated-CorTeX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcortex-gears
executable file
·200 lines (173 loc) · 6.41 KB
/
cortex-gears
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/usr/bin/perl
# /=====================================================================\ #
# | CorTeX Framework | #
# | Gears - Scheduler and Gearman Client Manager | #
# |=====================================================================| #
# | Part of the LaMaPUn project: https://trac.kwarc.info/lamapun/ | #
# | Research software, produced as part of work done by: | #
# | the KWARC group at Jacobs University | #
# | Copyright (c) 2012 | #
# | Released under the GNU Public License | #
# |---------------------------------------------------------------------| #
# | Deyan Ginev <[email protected]> #_# | #
# | http://kwarc.info/people/dginev (o o) | #
# \=========================================================ooo==U==ooo=/ #
use strict;
use warnings;
use Encode;
use JSON::XS qw(encode_json decode_json);
use Data::Dumper;
use FindBin;
my $RealBin_safe;
BEGIN {
$FindBin::RealBin =~ /^([^\0]+)\z/; # Valid Unix path TODO: Windows, revisit regexp
$RealBin_safe = $1;
die 'Fatal:IO:tainted RealBin was tainted! Failing...'
unless ($RealBin_safe && (-e $RealBin_safe.'/cortex-client')); }
use File::Basename;
my ($FILE_BASE,$libdir);
BEGIN {
$FILE_BASE = dirname(__FILE__);
$libdir = $FILE_BASE."/lib"; }
if (-d $libdir) {
use lib $libdir; }
use CorTeX::Util::DB_File_Utils qw(db_file_connect db_file_disconnect);
use CorTeX::Util::Compare qw(same_set);
use CorTeX::Backend;
use Unix::Processors;
my $check_interval = 10;
{
# Set up global state
local $SIG{'INT'} = \&stop_all; # Interrupt handler
local $SIG{'HUP'} = \&stop_all; # Apache Hangup handler
local $SIG{'KILL'} = \&stop_all; # Just good-old KILL handler
my ($MAIN_REPOS,$META_GRAPH,$BUILD_SYSTEM_URL) = @ARGV;
my $Cache={ clients=>[], exist_url=>'', sesame_url=>'', servers=>[] }; # Catalogue the child processes
$Cache->{processor_multiplier} = 2 * Unix::Processors->new->max_online;
my $db_handle = db_file_connect;
my $backend = CorTeX::Backend->new(%$db_handle);
db_file_disconnect($db_handle);
# Register default services
$Cache->{default_service_ids} = register_defaults();
# Start cron loop managing the client and worker children
while (1) { # Every minute, check:
# Reinit, When servers or backends change
if (setup_changed()) {
# Halt what we're doing
stop_children();
# Add/update all default services (if necessary)
# Grab a backend with the updated info
$db_handle = db_file_connect;
$backend = CorTeX::Backend->new(%$db_handle);
# Make sure we clean up after we halted
$backend->taskdb->mark_limbo_entries_queued;
db_file_disconnect($db_handle);
# Start clients
spawn_clients(); }
my $taskdb = $backend->taskdb;
# In case things just died away, respawn them:
spawn_clients() unless (@{$Cache->{clients}} > 0);
# Check again in a minute...
sleep $check_interval; }
sub spawn_clients {
my @servers = @{$Cache->{servers}};
# Servers x processors = # clients
for my $num(1..($Cache->{processor_multiplier}*scalar(@servers))) {
# Fork a job for each one!
my $pid = fork();
if ($pid == 0) {
exec("$RealBin_safe/cortex-client",@servers);
} else {
print STDERR "Started Client #$num : process $pid\n";
push @{$Cache->{clients}}, $pid;
}
}}
sub stop_all {
stop_children();
exit 0; }
sub stop_children {
stop_clients(); }
sub stop_clients {
stop_child($_) foreach @{$Cache->{clients}};
$Cache->{clients} = []; }
sub stop_child {
my ($pid) = @_;
# Send a SIGINT to the child job
kill 2, $pid;
waitpid($pid,0); }
sub setup_changed {
my $reinitialize_needed = 0;
$db_handle = db_file_connect;
my $sesame_url = $db_handle->{sesame_url}||'';
my $exist_url = $db_handle->{exist_url}||'';
my @servers = split("\n",$db_handle->{gearman_urls}||'');
db_file_disconnect($db_handle);
if ($Cache->{exist_url} ne $exist_url) {
$reinitialize_needed = 1;
$Cache->{exist_url} = $exist_url; }
if ($Cache->{sesame_url} ne $sesame_url) {
$reinitialize_needed = 1;
$Cache->{sesame_url} = $sesame_url; }
if (! same_set($Cache->{servers},\@servers)) {
$reinitialize_needed = 1;
@{$Cache->{servers}} = @servers; }
return $reinitialize_needed; }
sub register_defaults {
our ($INSTALLDIR) = grep(-d $_, map("$_/CorTeX", @INC));
my $services_dir = $INSTALLDIR."/Default";
opendir(my $dh, $services_dir)
|| die "can't opendir $services_dir: $!";
my @default_service_descriptions = grep { /\.json$/ && -f "$services_dir/$_" }
readdir($dh);
closedir $dh;
my @default_service_ids = ();
if (@default_service_descriptions) {
use File::Slurp;
my $dbhandle = db_file_connect;
require CorTeX::Backend;
my $backend = CorTeX::Backend->new(%$dbhandle);
my $current_services = $backend->taskdb->current_services;
db_file_disconnect($dbhandle);
foreach my $service_file(@default_service_descriptions) {
my $service_description = decode_json(read_file( "$services_dir/$service_file" ));
my ($id) = split(/.json/,$service_file);
push @default_service_ids, $id;
my $name = $service_description->{name};
$service_description->{id} = $id;
my @all_services = (@{$current_services->{1}},@{$current_services->{2}},@{$current_services->{3}});
unless (grep {$name eq $_} @all_services) {
$backend->taskdb->register_service(%$service_description);
}
}
}
return \@default_service_ids;
}
}
__END__
=pod
=head1 NAME
C<cortex-gears> - Scheduler of the CorTeX framework
=head1 SYNOPSIS
TODO
=head1 DESCRIPTION
TODO
=head1 Gearman Installation
Under Debian-based systems:
sudo apt-get install
gearman
gearman-job-server
gearman-tools
gearman-server
mod-gearman-tools
libgearman-client-async-perl
libmodule-install-xsutil-perl
libgearman-dev
cpan Gearman::XS::Client
cpan Gearman::XS::Worker
=head1 AUTHOR
Deyan Ginev <[email protected]>
=head1 COPYRIGHT
Research software, produced as part of work done by
the KWARC group at Jacobs University Bremen.
Released under the GNU Public License
=cut