Valley.pm 4.95 KB
Newer Older
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
=pod 

=head1 NAME

  Bio::EnsEMBL::Hive::Valley

=head1 SYNOPSIS

=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.

=head1 CONTACT

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

=cut

package Bio::EnsEMBL::Hive::Valley;

use strict;
use warnings;
26
use Sys::Hostname;
27
use Bio::EnsEMBL::Hive::Utils ('find_submodules');
28
use Bio::EnsEMBL::Hive::Limiter;
29

30
31
use base ('Bio::EnsEMBL::Hive::Configurable');

32
33
34
35
36
37
38
39

sub meadow_class_path {

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


sub new {
40
    my ($class, $config, $default_meadow_type, $pipeline_name) = @_;
41
42
43

    my $self = bless {}, $class;

44
45
46
    $self->config( $config );
    $self->context( [ 'Valley' ] );

47
    my $amh = $self->available_meadow_hash( {} );
48
49
50
51

        # 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";
52
        if($meadow_class->name) {
53
            my $meadow_object            = $meadow_class->new( $config );
54
55
56

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

57
            $amh->{$meadow_class->type} = $meadow_object;
58
59
60
        }
    }

61
    $self->set_default_meadow_type($default_meadow_type);     # run this method even if $default_meadow_type was not specified
62
63
64
65
66

    return $self;
}


67
sub available_meadow_hash {
68
69
70
    my $self = shift @_;

    if(@_) {
71
        $self->{_available_meadow_hash} = shift @_;
72
    }   
73
    return $self->{_available_meadow_hash};
74
75
76
}


77
sub get_available_meadow_list {     # this beautiful one-liner pushes $local to the bottom of the list
78
79
80
81
    my $self = shift @_;

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

82
    return [ sort { (ref($a) eq $local) or -(ref($b) eq $local) } values %{ $self->available_meadow_hash } ];
83
84
85
}


86
87
sub set_default_meadow_type {
    my ($self, $default_meadow_type) = @_;
88

89
90
91
    if($default_meadow_type) {
        if( my $default_meadow = $self->available_meadow_hash->{$default_meadow_type} ) {   # store if available
            $self->{_default_meadow} = $default_meadow;
92
        } else {
93
            die "Meadow '$default_meadow_type' does not seem to be available on this machine, please investigate";
94
        }
95
    } else {
96
        $self->{_default_meadow} = $self->get_available_meadow_list->[0];     # take the first from preference list
97
98
99
100
    }
}


101
sub get_default_meadow {
102
103
    my $self = shift @_;

104
    return $self->{_default_meadow};
105
106
107
108
109
110
}


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

111
112
    if( my $meadow = $self->available_meadow_hash->{$worker->meadow_type} ) {
        if($meadow->name eq $worker->meadow_name) {
113
114
            return $meadow;
        }
115
    }
116
    return undef;
117
118
119
}


120
sub whereami {
121
122
    my $self = shift @_;

123
    my ($meadow_type, $meadow_name, $pid);
124
    foreach my $meadow (@{ $self->get_available_meadow_list }) {
125
        eval {
126
127
128
            $pid         = $meadow->get_current_worker_process_id();
            $meadow_type = $meadow->type();
            $meadow_name = $meadow->name();
129
130
131
132
133
134
135
136
137
138
139
        };
        unless($@) {
            last;
        }
    }
    unless($pid) {
        die "Could not determine the Meadow, please investigate";
    }

    my $exechost = hostname();

140
    return ($meadow_type, $meadow_name, $pid, $exechost);
141
142
143
}


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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);
}


160
sub get_meadow_capacity_hash_by_meadow_type {
161
162
    my $self = shift @_;

163
    my %meadow_capacity_hash = ();
164
165

    foreach my $meadow (@{ $self->get_available_meadow_list }) {
166
167
168
169
170

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

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

175
    return \%meadow_capacity_hash;
176
177
178
}


179
180
181
182
183
184
185
186
187
188
189
190
191
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;
}


192
193
1;