RoleAdaptor.pm 4.59 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
=pod

=head1 NAME

    Bio::EnsEMBL::Hive::DBSQL::RoleAdaptor

=head1 SYNOPSIS

    $role_adaptor = $db_adaptor->get_RoleAdaptor;

    $role_adaptor = $role_object->adaptor;

=head1 DESCRIPTION

    Module to encapsulate all db access for persistent class Role.
    There should be just one per application and database connection.

=head1 LICENSE

20
    Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
Brandon Walts's avatar
Brandon Walts committed
21
    Copyright [2016-2020] EMBL-European Bioinformatics Institute
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

    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.

=head1 CONTACT

    Please subscribe to the Hive mailing list:  http://listserver.ebi.ac.uk/mailman/listinfo/ehive-users  to discuss Hive-related questions or to be notified of our updates

=cut


package Bio::EnsEMBL::Hive::DBSQL::RoleAdaptor;

use strict;
42
use warnings;
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
use Bio::EnsEMBL::Hive::Role;

use base ('Bio::EnsEMBL::Hive::DBSQL::ObjectAdaptor');


sub default_table_name {
    return 'role';
}


sub default_insertion_method {
    return 'INSERT';
}


sub object_class {
    return 'Bio::EnsEMBL::Hive::Role';
}


sub finalize_role {
64
    my ($self, $role, $release_undone_jobs) = @_;
65 66 67 68

    my $role_id         = $role->dbID;
    my $when_finished   = $role->when_finished ? "'".$role->when_finished."'" : 'CURRENT_TIMESTAMP';

69
    $self->dbc->do( "UPDATE role SET when_finished=$when_finished WHERE role_id=$role_id" );
70

71
    $self->db->get_AnalysisStatsAdaptor->increment_a_counter( 'num_running_workers', -1, $role->analysis_id );
72

73
    if( $release_undone_jobs ) {
74 75 76 77
        $self->db->get_AnalysisJobAdaptor->release_undone_jobs_from_role( $role );
    }

        # Re-sync the analysis_stats when a worker dies as part of dynamic sync system.
78
        # It will also re-calculate num_running_workers (from active roles)
79 80
        # so no further adjustment should be necessary.
    $self->db->get_WorkerAdaptor->safe_synchronize_AnalysisStats( $role->analysis->stats );
81 82 83
}


84
sub fetch_last_unfinished_by_worker_id {
85 86
    my ($self, $worker_id) = @_;

87
    return $self->fetch_all( "WHERE worker_id=$worker_id AND when_finished IS NULL ORDER BY role_id DESC LIMIT 1", 1 );
88 89
}

90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

sub get_hive_current_load {
    my $self = shift;
    my $sql = qq{
        SELECT sum(1/hive_capacity)
        FROM role
        JOIN analysis_stats USING(analysis_id)
        WHERE when_finished IS NULL
        AND hive_capacity IS NOT NULL
        AND hive_capacity>0
    };
    my $sth = $self->prepare($sql);
    $sth->execute();
    my ($current_load)=$sth->fetchrow_array();
    $sth->finish;
    return ($current_load || 0);
}


109 110 111 112 113 114 115
sub get_role_rank {
    my ($self, $role) = @_;

    return $self->count_all( 'analysis_id=' . $role->analysis_id . ' AND when_finished IS NULL AND role_id<' . $role->dbID );
}


116 117 118
sub count_active_roles {
    my ($self, $analysis_id) = @_;

119
    return $self->count_all( ($analysis_id ? "analysis_id=$analysis_id AND " : '') . 'when_finished IS NULL' );
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
sub print_active_role_counts {
    my $self = shift;

    my $sql = qq{
        SELECT logic_name, count(*)
        FROM role
        JOIN analysis_base a USING(analysis_id)
        WHERE when_finished IS NULL
        GROUP BY a.analysis_id
    };

    my $total_roles = 0;
    my $sth = $self->prepare($sql);
    $sth->execute();

    print "\n===== Stats of active Roles as recorded in the pipeline database: ======\n";
    while(my ($logic_name, $active_role_count) = $sth->fetchrow_array()) {
        printf("%30s : %d active Roles\n", $logic_name, $active_role_count);
        $total_roles += $active_role_count;
    }
    $sth->finish;
    printf("%30s : %d active Roles\n\n", '======= TOTAL =======', $total_roles);
}


148 149 150
sub fetch_all_finished_roles_with_unfinished_jobs {
    my $self = shift;

151 152
        # the list should contain all status'es that are not "in progress":
    return $self->fetch_all( "JOIN job USING(role_id) WHERE when_finished IS NOT NULL AND status NOT IN ('DONE', 'READY', 'FAILED', 'PASSED_ON', 'SEMAPHORED') GROUP BY role_id" );
153 154 155
}


156 157 158 159 160 161 162
sub fetch_all_unfinished_roles_of_dead_workers {
    my $self = shift;

    return $self->fetch_all( "JOIN worker USING(worker_id) WHERE when_finished IS NULL AND status='DEAD'" );
}


163 164
1;