Skip to content

Commit

Permalink
fix(core): DB transaction issue (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
garnier-quentin committed Dec 4, 2020
1 parent a277280 commit f319e26
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 39 deletions.
19 changes: 18 additions & 1 deletion gorgone/gorgone/class/core.pm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ my ($gorgone);
use base qw(gorgone::class::script);

my $VERSION = '1.0';
my %handlers = (TERM => {}, HUP => {}, CHLD => {});
my %handlers = (TERM => {}, HUP => {}, CHLD => {}, DIE => {});

sub new {
my $class = shift;
Expand Down Expand Up @@ -214,6 +214,8 @@ sub set_signal_handlers {
$handlers{HUP}->{$self} = sub { $self->handle_HUP() };
$SIG{CHLD} = \&class_handle_CHLD;
$handlers{CHLD}->{$self} = sub { $self->handle_CHLD() };
$SIG{__DIE__} = \&class_handle_DIE;
$handlers{DIE}->{$self} = sub { $self->handle_DIE($_[0]) };
}

sub class_handle_TERM {
Expand All @@ -234,6 +236,14 @@ sub class_handle_CHLD {
}
}

sub class_handle_DIE {
my ($msg) = @_;

foreach (keys %{$handlers{DIE}}) {
&{$handlers{DIE}->{$_}}($msg);
}
}

sub handle_TERM {
my ($self) = @_;
$self->{logger}->writeLogInfo("[core] $$ Receiving order to stop...");
Expand Down Expand Up @@ -263,6 +273,13 @@ sub handle_CHLD {
$SIG{CHLD} = \&class_handle_CHLD;
}

sub handle_DIE {
my $self = shift;
my $msg = shift;

$self->{logger}->writeLogError("[core] Receiving DIE: $msg");
}

sub unload_module {
my ($self, %options) = @_;

Expand Down
41 changes: 33 additions & 8 deletions gorgone/gorgone/class/db.pm
Original file line number Diff line number Diff line change
Expand Up @@ -142,24 +142,46 @@ sub set_inactive_destroy {
}

sub transaction_mode {
my ($self, $status) = @_;
my ($self, $mode) = @_;

if ($status) {
$self->{instance}->begin_work;
my $status;
if (!defined($self->{instance})) {
$status = $self->connect();
return -1 if ($status == -1);
}

if ($mode) {
$status = $self->{instance}->begin_work();
if (!$status) {
$self->error($self->{instance}->errstr, 'begin work');
return -1;
}
$self->{transaction_begin} = 1;
$self->{instance}->{RaiseError} = 1;
} else {
$self->{transaction_begin} = 0;
$self->{instance}->{AutoCommit} = 1;
$self->{instance}->{RaiseError} = 0;
}

return 0;
}

sub commit {
my ($self) = @_;

$self->{instance}->commit;
if (!defined($self->{instance})) {
$self->{transaction_begin} = 0;
return -1;
}

my $status = $self->{instance}->commit();
$self->{transaction_begin} = 0;

if (!$status) {
$self->error($self->{instance}->errstr, 'commit');
return -1;
}

return 0;
}

sub rollback {
Expand Down Expand Up @@ -238,6 +260,7 @@ sub connect() {
sleep(1);
$count++;
}

return $status;
}

Expand All @@ -254,7 +277,7 @@ sub disconnect {
sub do {
my ($self, $query) = @_;

if (!defined $self->{instance}) {
if (!defined($self->{instance})) {
if ($self->connect() == -1) {
$self->{logger}->writeLogError("Cannot connect to database");
return -1;
Expand Down Expand Up @@ -298,7 +321,7 @@ sub query {
}
$self->{args} = [];
}
if ($status == -1 && $self->{force} != 1) {
if ($status == -1) {
$self->{args} = [];
last;
}
Expand Down Expand Up @@ -326,8 +349,10 @@ sub query {
sleep(1);
next;
}

last;
}

return ($status, $statement_handle);
}

Expand Down
41 changes: 32 additions & 9 deletions gorgone/gorgone/class/sqlquery.pm
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ sub execute {
sub transaction_query_multi {
my ($self, %options) = @_;

$self->transaction_mode(1);
my ($status, $sth) = $self->{db_centreon}->query($options{request}, prepare_only => 1);
my ($status, $sth);

$status = $self->transaction_mode(1);
return -1 if ($status == -1);

($status, $sth) = $self->{db_centreon}->query($options{request}, prepare_only => 1);
if ($status == -1) {
$self->rollback();
return -1;
Expand All @@ -100,21 +104,28 @@ sub transaction_query_multi {
}
} while ($sth->more_results);

$self->commit();
$status = $self->commit();
return -1 if ($status == -1);

return 0;
}

sub transaction_query {
my ($self, %options) = @_;
my $status;

$self->transaction_mode(1);
my ($status) = $self->do(request => $options{request});
$status = $self->transaction_mode(1);
return -1 if ($status == -1);

($status) = $self->do(request => $options{request});
if ($status == -1) {
$self->rollback();
return -1;
}

$self->commit();
$status = $self->commit();
return -1 if ($status == -1);

return 0;
}

Expand All @@ -124,10 +135,22 @@ sub quote {
return $self->{db_centreon}->quote($options{value});
}

sub transaction_mode { shift->{db_centreon}->transaction_mode($_[0]); };
sub transaction_mode {
my ($self) = @_;

return $self->{db_centreon}->transaction_mode($_[1]);
};

sub commit { shift->{db_centreon}->commit(); }
sub commit {
my ($self, %options) = @_;

return $self->{db_centreon}->commit();
}

sub rollback { shift->{db_centreon}->rollback(); }
sub rollback {
my ($self, %options) = @_;

return $self->{db_centreon}->rollback();
}

1;
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,9 @@ sub new {

sub database_init_transaction {
my ($self, %options) = @_;

eval {
$self->{class_object_centreon}->{db_centreon}->transaction_mode(1);
};
if ($@) {

my $status = $self->{class_object_centreon}->{db_centreon}->transaction_mode(1);
if ($status == -1) {
$self->{logger}->writeLogError("$@");
return -1;
}
Expand All @@ -75,14 +73,13 @@ sub database_init_transaction {
sub database_commit_transaction {
my ($self, %options) = @_;

eval {
$self->{class_object_centreon}->commit();
$self->{class_object_centreon}->transaction_mode(0);
};
if ($@) {
my $status = $self->{class_object_centreon}->commit();
if ($status == -1) {
$self->{logger}->writeLogError("$@");
return -1;
}

$self->{class_object_centreon}->transaction_mode(0);
return 0;
}

Expand Down
32 changes: 28 additions & 4 deletions gorgone/gorgone/modules/core/dbcleaner/class.pm
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use ZMQ::LibZMQ4;
use ZMQ::Constants qw(:all);
use JSON::XS;

my %handlers = (TERM => {}, HUP => {});
my %handlers = (TERM => {}, HUP => {}, DIE => {});
my ($connector);

sub new {
Expand All @@ -52,6 +52,8 @@ sub set_signal_handlers {
$handlers{TERM}->{$self} = sub { $self->handle_TERM() };
$SIG{HUP} = \&class_handle_HUP;
$handlers{HUP}->{$self} = sub { $self->handle_HUP() };
$SIG{__DIE__} = \&class_handle_DIE;
$handlers{DIE}->{$self} = sub { $self->handle_DIE($_[0]) };
}

sub handle_HUP {
Expand All @@ -65,6 +67,22 @@ sub handle_TERM {
$self->{stop} = 1;
}

sub handle_DIE {
my $self = shift;
my $msg = shift;

$self->{logger}->writeLogError("[dbcleaner] Receiving DIE: $msg");
$self->exit_process();
}

sub class_handle_DIE {
my ($msg) = @_;

foreach (keys %{$handlers{DIE}}) {
&{$handlers{DIE}->{$_}}($msg);
}
}

sub class_handle_TERM {
foreach (keys %{$handlers{TERM}}) {
&{$handlers{TERM}->{$_}}();
Expand All @@ -77,6 +95,14 @@ sub class_handle_HUP {
}
}

sub exit_process {
my ($self, %options) = @_;

$self->{logger}->writeLogInfo("[dbcleaner] $$ has quit");
zmq_close($self->{internal_socket});
exit(0);
}

sub action_dbclean {
my ($self, %options) = @_;

Expand Down Expand Up @@ -180,9 +206,7 @@ sub run {
# we try to do all we can
my $rev = zmq_poll($self->{poll}, 5000);
if (defined($rev) && $rev == 0 && $self->{stop} == 1) {
$self->{logger}->writeLogInfo("[dbcleaner] $$ has quit");
zmq_close($connector->{internal_socket});
exit(0);
$self->exit_process();
}

$self->action_dbclean(cycle => 1);
Expand Down
20 changes: 14 additions & 6 deletions gorgone/gorgone/modules/core/proxy/hooks.pm
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,11 @@ sub setlogs {
$synctime_nodes->{ $options{data}->{data}->{id} }->{in_progress} = 0;

my $ctime_recent = 0;
# Transaction. We don't use last_id (problem if it's clean the sqlite table
$options{dbh}->transaction_mode(1);
my $status = 0;
# Transaction. We don't use last_id (problem if it's clean the sqlite table).
my $status;
$status = $options{dbh}->transaction_mode(1);
return -1 if ($status == -1);

foreach (@{$options{data}->{data}->{result}}) {
# wrong timestamp inserted. we skip it
if ($_->{ctime} !~ /[0-9\.]/) {
Expand All @@ -571,13 +573,17 @@ sub setlogs {
$ctime_recent = $_->{ctime} if ($ctime_recent < $_->{ctime});
}
if ($status == 0 && update_sync_time(dbh => $options{dbh}, id => $options{data}->{data}->{id}, ctime => $ctime_recent) == 0) {
$options{dbh}->commit();
$status = $options{dbh}->commit();
return -1 if ($status == -1);
$options{dbh}->transaction_mode(0);

$synctime_nodes->{$options{data}->{data}->{id}}->{ctime} = $ctime_recent if ($ctime_recent != 0);
} else {
$options{dbh}->rollback();
$options{dbh}->transaction_mode(0);
return -1;
}
$options{dbh}->transaction_mode(0);


# We try to send it to parents
foreach (keys %{$parent_ping}) {
gorgone::class::core::send_message_parent(
Expand All @@ -589,6 +595,8 @@ sub setlogs {
token => undef,
);
}

return 0;
}

sub ping_send {
Expand Down
2 changes: 1 addition & 1 deletion gorgone/gorgone/standard/library.pm
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ sub init_database {
port => $options{port},
user => $options{user},
password => $options{password},
force => 1,
force => 2,
logger => $options{logger}
);
$options{gorgone}->{db_gorgone}->set_inactive_destroy();
Expand Down

0 comments on commit f319e26

Please sign in to comment.