9 This is the
'Local' implementation of
Meadow 13 Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
14 Copyright [2016-2022] EMBL-European Bioinformatics Institute
16 Licensed under the Apache License,
Version 2.0 (the
"License"); you may not use
this file except in compliance with the License.
17 You may obtain a copy of the License at
21 Unless required by applicable law or agreed to in writing, software distributed under the License
22 is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 See the License
for the specific language governing permissions and limitations under the License.
27 Please subscribe to the
Hive mailing list: http:
32 package Bio::EnsEMBL::Hive::Meadow::LOCAL;
39 # -------------------------------------------------------------------------------------------------------------------- 40 # <hack> What follows is a hack to extend the built-in exec() function that is called by Proc::Daemon . 41 # The extended version also understands an ARRAYref as valid input and turns it into a LIST. 42 # Thanks to this we can avoid calling an extra shell to interpret the command line being daemonized. 43 # -------------------------------------------------------------------------------------------------------------------- 46 *Proc::Daemon::exec = sub {
47 return ( ref($_[0]) eq
'ARRAY' ) ? CORE::exec( @{$_[0]} ) : CORE::exec( @_ );
51 use Proc::Daemon 0.23; # NB:
this line absolutely must come after the BEGIN block that redefines exec(), or the trick will fail.
53 # --------------------------------------------------------------------------------------------------------------------
55 # -------------------------------------------------------------------------------------------------------------------- 58 use base (
'Bio::EnsEMBL::Hive::Meadow');
61 our $VERSION =
'5.0'; # Semantic version of the
Meadow interface:
62 # change the Major version whenever an incompatible change is introduced, 63 # change the Minor version whenever the interface is extended, but compatibility is retained. 66 sub name { # also called to check
for availability;
for the moment assume
LOCAL meadow is always available
69 return (split(/\./, $self->get_current_hostname() ))[0]; # only take the first name
73 sub get_current_worker_process_id {
79 sub deregister_local_process {} # Nothing to
do 81 sub _command_line_to_extract_all_running_workers {
84 # Make sure we have excluded both 'awk' itself and commands like "less runWorker.pl" : 85 return q{ps ex -o state,user,pid,command -w -w | awk
'((/runWorker.pl/ || /beekeeper.pl/) && ($4 ~ /perl[[:digit:].]*$/) )'};
89 sub status_of_all_our_workers { # returns an arrayref
93 my $job_name_prefix = $self->job_name_prefix();
96 foreach my $line (`$cmd`) {
97 my ($pre_status, $meadow_user, $worker_pid, @job_name) = split(/\s+/, $line);
100 'R' =>
'RUN', # running
102 'S' =>
'RUN', # sleeping (sleeping
for less than 20 sec on a Mac)
103 'I' =>
'RUN', # Mac: idle (sleeping
for more than 20 sec)
105 'D' =>
'RUN', # Linux: uninterruptible sleep, usually IO
106 'U' =>
'RUN', # Mac: uninterruptible wait
108 'T' =>
'SSUSP' # stopped process
109 }->{ substr($pre_status,0,1) }; # only take the first character because of Mac
's additional modifiers 111 # Note: you can locally 'kill -19
' a worker to suspend it and 'kill -18
' a worker to resume it 113 # Exclude workers from other pipelines 114 if (join(' ', @job_name) =~ / EHIVE_SUBMISSION_NAME=(\S+)/) { 115 unless ($1 =~ /^$job_name_prefix/) { 120 push @status_list, [$worker_pid, $meadow_user, $status]; 122 return \@status_list; 126 sub check_worker_is_alive_and_mine { 127 my ($self, $worker) = @_; 129 my $wpid = $worker->process_id(); 130 my $is_alive_and_mine = kill 0, $wpid; 132 return $is_alive_and_mine; 137 my ($self, $worker, $fast) = @_; 139 system('kill
', '-9
', $worker->process_id()); 143 sub submit_workers_return_meadow_pids { 144 my ($self, $worker_cmd, $required_worker_count, $iteration, $rc_name, $rc_specific_submission_cmd_args, $submit_log_subdir) = @_; 146 my $worker_cmd_components = [ split_for_bash($worker_cmd) ]; 148 my $job_name = $self->job_array_common_name($rc_name, $iteration); 149 $ENV{EHIVE_SUBMISSION_NAME} = $job_name; 151 my @children_pids = (); 153 print "Spawning [ ".$self->signature." ] x$required_worker_count \t\t$worker_cmd\n"; 155 foreach my $idx (1..$required_worker_count) { 157 my $child_pid = Proc::Daemon::Init( { 158 $submit_log_subdir ? ( 159 child_STDOUT => $submit_log_subdir . "/log_${iteration}_${rc_name}_${idx}_$$.out", 160 child_STDERR => $submit_log_subdir . "/log_${iteration}_${rc_name}_${idx}_$$.err", 161 ) : (), # both STD streams are sent to /dev/null by default 163 exec_command => [ $worker_cmd_components ], # the AoA format is supported thanks to the BEGIN hack introduced in the beginning of this module. 166 push @children_pids, $child_pid; 169 return \@children_pids; 173 sub run_on_host { # Overrides Meadow::run_on_host 174 my ($self, $meadow_host, $meadow_user, $command) = @_; 175 # We can assume the current host is $meadow_host and bypass ssh 176 return system(@$command);
protected _command_line_to_extract_all_running_workers()