9 This is the
'Local' implementation of Meadow
13 See the NOTICE file distributed with
this work
for additional information
14 regarding copyright ownership.
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 my $exec_status = system('kill
', '-9
', $worker->process_id());
140 return ( $exec_status >> 8 );
144 sub submit_workers_return_meadow_pids {
145 my ($self, $worker_cmd, $required_worker_count, $iteration, $rc_name, $rc_specific_submission_cmd_args, $submit_log_subdir) = @_;
147 my $worker_cmd_components = [ split_for_bash($worker_cmd) ];
149 my $job_name = $self->job_array_common_name($rc_name, $iteration);
150 $ENV{EHIVE_SUBMISSION_NAME} = $job_name;
152 my @children_pids = ();
154 print "Spawning [ ".$self->signature." ] x$required_worker_count \t\t$worker_cmd\n";
156 foreach my $idx (1..$required_worker_count) {
158 my $child_pid = Proc::Daemon::Init( {
159 $submit_log_subdir ? (
160 child_STDOUT => $submit_log_subdir . "/log_${iteration}_${rc_name}_${idx}_$$.out",
161 child_STDERR => $submit_log_subdir . "/log_${iteration}_${rc_name}_${idx}_$$.err",
162 ) : (), # both STD streams are sent to /dev/null by default
164 exec_command => [ $worker_cmd_components ], # the AoA format is supported thanks to the BEGIN hack introduced in the beginning of this module.
167 push @children_pids, $child_pid;
170 return \@children_pids;
174 sub run_on_host { # Overrides Meadow::run_on_host
175 my ($self, $meadow_host, $meadow_user, $command) = @_;
176 # We can assume the current host is $meadow_host and bypass ssh
177 return system(@$command);