Valley.pm 5.59 KB
Newer Older
1 2 3 4
=pod 

=head1 NAME

5
    Bio::EnsEMBL::Hive::Valley
6 7 8 9 10 11 12 13

=head1 DESCRIPTION

    A Valley represents a collection of available Meadows.

    Certain methods fit better with the concept of Valley -
    such as identifying all dead workers, or killing a particular one given worker_id.

14 15
=head1 LICENSE

16
    Copyright [1999-2014] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
17 18 19 20 21 22 23 24 25 26

    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License
    is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and limitations under the License.

27 28
=head1 CONTACT

29
    Please contact ehive-users@ebi.ac.uk mailing list with questions/suggestions.
30 31 32

=cut

33

34 35 36 37
package Bio::EnsEMBL::Hive::Valley;

use strict;
use warnings;
38
use Sys::Hostname;
39
use Bio::EnsEMBL::Hive::Utils ('find_submodules');
40
use Bio::EnsEMBL::Hive::Limiter;
41

42 43
use base ('Bio::EnsEMBL::Hive::Configurable');

44 45 46 47 48 49 50 51

sub meadow_class_path {

    return 'Bio::EnsEMBL::Hive::Meadow';
}


sub new {
52
    my ($class, $config, $default_meadow_type, $pipeline_name) = @_;
53 54 55

    my $self = bless {}, $class;

56 57 58
    $self->config( $config );
    $self->context( [ 'Valley' ] );

59
    my $amh = $self->available_meadow_hash( {} );
60 61 62 63

        # make sure modules are loaded and available ones are checked prior to setting the current one
    foreach my $meadow_class (@{ find_submodules( $self->meadow_class_path ) }) {
        eval "require $meadow_class";
64
        if($meadow_class->name) {
65
            my $meadow_object            = $meadow_class->new( $config );
66 67 68

            $meadow_object->pipeline_name( $pipeline_name ) if($pipeline_name);

69
            $amh->{$meadow_class->type} = $meadow_object;
70 71 72
        }
    }

73
    $self->set_default_meadow_type($default_meadow_type);     # run this method even if $default_meadow_type was not specified
74 75 76 77 78

    return $self;
}


79
sub available_meadow_hash {
80 81 82
    my $self = shift @_;

    if(@_) {
83
        $self->{_available_meadow_hash} = shift @_;
84
    }   
85
    return $self->{_available_meadow_hash};
86 87 88
}


89
sub get_available_meadow_list {     # this beautiful one-liner pushes $local to the bottom of the list
90 91 92 93
    my $self = shift @_;

    my $local = $self->meadow_class_path . '::LOCAL';

94
    return [ sort { (ref($a) eq $local) or -(ref($b) eq $local) } values %{ $self->available_meadow_hash } ];
95 96 97
}


98 99
sub set_default_meadow_type {
    my ($self, $default_meadow_type) = @_;
100

101 102 103
    if($default_meadow_type) {
        if( my $default_meadow = $self->available_meadow_hash->{$default_meadow_type} ) {   # store if available
            $self->{_default_meadow} = $default_meadow;
104
        } else {
105
            die "Meadow '$default_meadow_type' does not seem to be available on this machine, please investigate";
106
        }
107
    } else {
108
        $self->{_default_meadow} = $self->get_available_meadow_list->[0];     # take the first from preference list
109 110 111 112
    }
}


113
sub get_default_meadow {
114 115
    my $self = shift @_;

116
    return $self->{_default_meadow};
117 118 119 120 121 122
}


sub find_available_meadow_responsible_for_worker {
    my ($self, $worker) = @_;

123 124
    if( my $meadow = $self->available_meadow_hash->{$worker->meadow_type} ) {
        if($meadow->name eq $worker->meadow_name) {
125 126
            return $meadow;
        }
127
    }
128
    return undef;
129 130 131
}


132
sub whereami {
133 134
    my $self = shift @_;

135
    my ($meadow_type, $meadow_name, $pid);
136
    foreach my $meadow (@{ $self->get_available_meadow_list }) {
137
        eval {
138 139 140
            $pid         = $meadow->get_current_worker_process_id();
            $meadow_type = $meadow->type();
            $meadow_name = $meadow->name();
141 142 143 144 145 146 147 148 149 150 151
        };
        unless($@) {
            last;
        }
    }
    unless($pid) {
        die "Could not determine the Meadow, please investigate";
    }

    my $exechost = hostname();

152
    return ($meadow_type, $meadow_name, $pid, $exechost);
153 154 155
}


156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
sub get_pending_worker_counts_by_meadow_type_rc_name {
    my $self = shift @_;

    my %pending_counts = ();
    my $total_pending_all_meadows = 0;

    foreach my $meadow (@{ $self->get_available_meadow_list }) {
        my ($pending_this_meadow_by_rc_name, $total_pending_this_meadow) = ($meadow->count_pending_workers_by_rc_name());
        $pending_counts{ $meadow->type } = $pending_this_meadow_by_rc_name;
        $total_pending_all_meadows += $total_pending_this_meadow;
    }

    return (\%pending_counts, $total_pending_all_meadows);
}


172
sub get_meadow_capacity_hash_by_meadow_type {
173 174
    my $self = shift @_;

175
    my %meadow_capacity_hash = ();
176 177

    foreach my $meadow (@{ $self->get_available_meadow_list }) {
178 179 180 181 182

        my $available_worker_slots = defined($meadow->config_get('TotalRunningWorkersMax'))
            ? $meadow->config_get('TotalRunningWorkersMax') - $meadow->count_running_workers
            : undef;

183
            # so the hash will contain limiters for every meadow_type, but not all of them active:
184
        $meadow_capacity_hash{ $meadow->type } = Bio::EnsEMBL::Hive::Limiter->new( "Number of workers in '".$meadow->signature."' meadow", $available_worker_slots );
185 186
    }

187
    return \%meadow_capacity_hash;
188 189 190
}


191 192 193 194 195 196 197 198 199 200 201 202 203
sub count_running_workers {     # just an aggregator
    my $self = shift @_;

    my $valley_running_workers = 0;

    foreach my $meadow (@{ $self->get_available_meadow_list }) {
        $valley_running_workers += $meadow->count_running_workers;
    }

    return $valley_running_workers;
}


204 205
1;