From: erickson Date: Thu, 31 Jan 2008 22:45:28 +0000 (+0000) Subject: comitting initial authoritative auto-magic transactions for cstore X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=dcadd91d709ecda026dde90ff26c98d4b7668f45;p=Evergreen.git comitting initial authoritative auto-magic transactions for cstore git-svn-id: svn://svn.open-ils.org/ILS/trunk@8562 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/src/perlmods/OpenILS/Application.pm b/Open-ILS/src/perlmods/OpenILS/Application.pm index 72290e4519..d9b8872de3 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application.pm @@ -1,5 +1,6 @@ package OpenILS::Application; use OpenSRF::Application; +use UNIVERSAL::require; use base qw/OpenSRF::Application/; sub ils_version { @@ -13,5 +14,49 @@ __PACKAGE__->register_method( method => 'ils_version', ); +sub register_method { + my $class = shift; + my %args = @_; + my %dup_args = %args; + + $class = ref($class) || $class; + + $args{package} ||= $class; + __PACKAGE__->SUPER::register_method( %args ); + + if (exists($dup_args{authoritative}) and $dup_args{authoritative}) { + (my $name = $dup_args{api_name}) =~ s/$/.authoritative/o; + if ($name ne $dup_args{api_name}) { + $dup_args{real_api_name} = $dup_args{api_name}; + $dup_args{method} = 'authoritative_wrapper'; + $dup_args{api_name} = $name; + $dup_args{package} = __PACKAGE__; + __PACKAGE__->SUPER::register_method( %dup_args ); + } + } +} + +sub authoritative_wrapper { + + if (!$OpenILS::Utils::CStoreEditor::_loaded) { + die "Couldn't load OpenILS::Utils::CStoreEditor!" unless 'OpenILS::Utils::CStoreEditor'->use; + } + + my $self = shift; + my $client = shift; + my @args = @_; + + my $method = $self->method_lookup($self->{real_api_name}); + die unless $method; + + local $OpenILS::Utils::CStoreEditor::always_xact = 1; + + $client->respond( $_ ) for ( $method->run(@args) ); + + OpenILS::Utils::CStoreEditor->flush_forced_xacts(); + + return undef; +} + 1; diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm b/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm index b54b5dbc1e..b7d0fbd2de 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm @@ -11,6 +11,10 @@ use OpenSRF::Utils::Logger qw($logger); my $U = "OpenILS::Application::AppUtils"; my %PERMS; my $cache; +my %xact_ed_cache; + +our $always_xact = 0; +our $_loaded = 1; #my %PERMS = ( # 'biblio.record_entry' => { update => 'UPDATE_MARC' }, @@ -19,7 +23,12 @@ my $cache; # 'action.circulation' => { retrieve => 'VIEW_CIRCULATIONS'}, #); - +sub flush_forced_xacts { + for my $k ( keys %xact_ed_cache ) { + $xact_ed_cache{$k}->rollback; + delete $xact_ed_cache{$k}; + } +} # ----------------------------------------------------------------------------- # Export some useful functions @@ -78,8 +87,13 @@ sub app { sub log { my( $self, $lev, $str ) = @_; my $s = "editor["; - $s .= "0|" unless $self->{xact}; - $s .= "1|" if $self->{xact}; + if ($always_xact) { + $s .= "!|"; + } elsif ($self->{xact}) { + $s .= "1|"; + } else { + $s .= "0|"; + } $s .= "0" unless $self->requestor; $s .= $self->requestor->id if $self->requestor; $s .= "]"; @@ -168,9 +182,11 @@ sub session { throw OpenSRF::EX::ERROR ($str); } - $self->{session}->connect if $self->{xact} or $self->{connect}; - $self->xact_start if $self->{xact}; + $self->{session}->connect if $self->{xact} or $self->{connect} or $always_xact; + $self->xact_start if $self->{xact} or $always_xact; } + + $xact_ed_cache{$self->{xact_id}} = $self if $always_xact; return $self->{session}; } @@ -181,8 +197,9 @@ sub session { sub xact_start { my $self = shift; $self->log(D, "starting new db session"); - my $stat = $self->request($self->app . '.transaction.begin'); + my $stat = $self->request($self->app . '.transaction.begin') unless $self->{xact_id}; $self->log(E, "error starting database transaction") unless $stat; + $self->{xact_id} = $stat; return $stat; } @@ -192,8 +209,9 @@ sub xact_start { sub xact_commit { my $self = shift; $self->log(D, "comitting db session"); - my $stat = $self->request($self->app.'.transaction.commit'); + my $stat = $self->request($self->app.'.transaction.commit') if $self->{xact_id}; $self->log(E, "error comitting database transaction") unless $stat; + delete $self->{xact_id}; return $stat; } @@ -204,7 +222,10 @@ sub xact_rollback { my $self = shift; return unless $self->{session}; $self->log(I, "rolling back db session"); - return $self->request($self->app.".transaction.rollback"); + my $stat = $self->request($self->app.".transaction.rollback") if $self->{xact_id}; + $self->log(E, "error rolling back database transaction") unless $stat; + delete $self->{xact_id}; + return $stat; } @@ -214,7 +235,7 @@ sub xact_rollback { # ----------------------------------------------------------------------------- sub rollback { my $self = shift; - $self->xact_rollback if $self->{xact}; + $self->xact_rollback; delete $self->{xact}; $self->disconnect; } @@ -231,7 +252,7 @@ sub disconnect { # ----------------------------------------------------------------------------- sub commit { my $self = shift; - return unless $self->{xact}; + return unless $self->{xact_id}; $self->xact_commit; $self->session->disconnect; $self->{session} = undef; @@ -270,7 +291,7 @@ sub request { $self->log(I, "request $method : $argstr"); - if( $self->{xact} and + if( ($self->{xact} or $always_xact) and $self->session->state != OpenSRF::AppSession::CONNECTED() ) { #$logger->error("CStoreEditor lost it's connection!!"); throw OpenSRF::EX::ERROR ("CStore connection timed out - transaction cannot continue"); @@ -545,7 +566,7 @@ sub runmethod { $self->clear_event; if( $action eq 'update' or $action eq 'delete' or $action eq 'create' ) { - if(!$self->{xact}) { + if(!$self->{xact_id}) { $logger->error("Attempt to update DB while not in a transaction : $method"); throw OpenSRF::EX::ERROR ("Attempt to update DB while not in a transaction : $method"); }