comitting initial authoritative auto-magic transactions for cstore
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 31 Jan 2008 22:45:28 +0000 (22:45 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 31 Jan 2008 22:45:28 +0000 (22:45 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@8562 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/perlmods/OpenILS/Application.pm
Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm

index 72290e4..d9b8872 100644 (file)
@@ -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;
 
index b54b5db..b7d0fbd 100644 (file)
@@ -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");
                }