Skip to content

Commit

Permalink
switching AJA to INSERT method, dealing with collisions via API
Browse files Browse the repository at this point in the history
  • Loading branch information
ens-lg4 committed Dec 22, 2016
1 parent 1a8fb01 commit ad5c1f7
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
35 changes: 34 additions & 1 deletion modules/Bio/EnsEMBL/Hive/DBSQL/AnalysisJobAdaptor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ sub default_table_name {


sub default_insertion_method {
return 'INSERT_IGNORE';
return 'INSERT';
}


Expand Down Expand Up @@ -125,6 +125,39 @@ sub fetch_by_analysis_id_and_input_id { # It is a special case not covered b
}


sub class_specific_execute {
my ($self, $object, $sth, $values) = @_;

my $return_code;

eval {
$return_code = $self->SUPER::class_specific_execute($object, $sth, $values);
1;
} or do {
my $duplicate_regex = {
'mysql' => qr/Duplicate entry.+?for key/s,
'sqlite' => qr/columns.+?are not unique|UNIQUE constraint failed/s, # versions around 3.8 spit the first msg, versions around 3.15 - the second
'pgsql' => qr/duplicate key value violates unique constraint/s,
}->{$self->db->dbc->driver};

if( $@ =~ $duplicate_regex ) { # implementing 'INSERT IGNORE' of Jobs on the API side
my $emitting_job_id = $object->prev_job_id;
my $analysis_id = $object->analysis_id;
my $input_id = $object->input_id;
my $msg = "Attempt to insert a duplicate job (analysis_id=$analysis_id, input_id=$input_id) intercepted and ignored";

$self->db->get_LogMessageAdaptor->store_job_message( $emitting_job_id, $msg, 'INFO' );

$return_code = '0E0';
} else {
die $@;
}
};

return $return_code;
}


=head2 store_jobs_and_adjust_counters
Arg [1] : arrayref of Bio::EnsEMBL::Hive::AnalysisJob $jobs_to_store
Expand Down
12 changes: 11 additions & 1 deletion modules/Bio/EnsEMBL/Hive/DBSQL/BaseAdaptor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,15 @@ sub check_object_present_in_db_by_content { # return autoinc_id/undef if the
}


sub class_specific_execute {
my ($self, $object, $sth, $values) = @_;

my $return_code = $sth->execute( @$values );

return $return_code;
}


sub store {
my ($self, $object_or_list) = @_;

Expand Down Expand Up @@ -546,9 +555,10 @@ sub store {
my $values_being_stored = $self->slicer( $object, $columns_being_stored );
# warn "STORED_VALUES: ".stringify($values_being_stored)."\n";

my $return_code = $this_sth->execute( @$values_being_stored )
my $return_code = $self->class_specific_execute($object, $this_sth, $values_being_stored )
# using $return_code in boolean context allows to skip the value '0E0' ('no rows affected') that Perl treats as zero but regards as true:
or throw("Could not store fields\n\t{$column_key}\nwith data:\n\t(".join(',', @$values_being_stored).')');

if($return_code > 0) { # <--- for the same reason we have to be explicitly numeric here
my $liid = $autoinc_id && $self->dbc->db_handle->last_insert_id(undef, undef, $table_name, $autoinc_id);
$self->mark_stored($object, $liid );
Expand Down
2 changes: 2 additions & 0 deletions sql/tables.pgsql
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ CREATE TABLE job (
CREATE INDEX ON job (analysis_id, status, retry_count); -- for claiming jobs
CREATE INDEX ON job (role_id, status); -- for fetching and releasing claimed jobs

/*
-- PostgreSQL is lacking INSERT IGNORE, so we need a RULE to silently
-- discard the insertion of duplicated entries in the job table
CREATE OR REPLACE RULE job_table_ignore_duplicate_inserts AS
Expand All @@ -378,6 +379,7 @@ CREATE OR REPLACE RULE job_table_ignore_duplicate_inserts AS
FROM job
WHERE job.input_id=NEW.input_id AND job.param_id_stack=NEW.param_id_stack AND job.accu_id_stack=NEW.accu_id_stack AND job.analysis_id=NEW.analysis_id)
DO INSTEAD NOTHING;
*/

/**
@table job_file
Expand Down

0 comments on commit ad5c1f7

Please sign in to comment.