about summary refs log tree commit homepage
path: root/lib/PublicInbox/MiscIdx.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-01-24 22:41:56 -0800
committerEric Wong <e@80x24.org>2021-01-26 18:51:31 +0000
commitaf3dfdc0416c7d9d5ad785826639744cc2cd9b9a (patch)
treed82cc9434fbc6c53f5f6085c9f916cc3bcce85bb /lib/PublicInbox/MiscIdx.pm
parent6c04afbcb4a090e739066d5ff1735775646c9a44 (diff)
downloadpublic-inbox-af3dfdc0416c7d9d5ad785826639744cc2cd9b9a.tar.gz
This fixes a sporadic failure on a 1/2 core VM where
"git cat-file --batch" hasn't started up by the time
$cleanup->() destroys the ALL.git directory in t/lei.t
(but not t/lei-oneshot.t).

This happens because dwaitpid() runs inside the event loop
asynchronously and we were able to return to the client before
the cat-file process could even start.

I could not reproduce this failure on my usual 4-core
workstation via "schedtool -a 0x1" to force the entire
test to use a single core.

Lazy transactions matches OverIdx and SearchIdx behavior, and
I've verified this lets us avoid problems with old Xapian
versions (on CentOS 7.x) which failed to set FD_CLOEXEC.
Diffstat (limited to 'lib/PublicInbox/MiscIdx.pm')
-rw-r--r--lib/PublicInbox/MiscIdx.pm19
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/PublicInbox/MiscIdx.pm b/lib/PublicInbox/MiscIdx.pm
index ab5e029a..f5a374b2 100644
--- a/lib/PublicInbox/MiscIdx.pm
+++ b/lib/PublicInbox/MiscIdx.pm
@@ -39,25 +39,30 @@ sub new {
         }, $class;
 }
 
-sub begin_txn {
+sub _begin_txn ($) {
         my ($self) = @_;
-        croak 'BUG: already in txn' if $self->{xdb}; # XXX make lazy?
         my $wdb = $PublicInbox::Search::X{WritableDatabase};
         my $xdb = eval { $wdb->new($self->{mi_dir}, $self->{flags}) };
         croak "Failed opening $self->{mi_dir}: $@" if $@;
-        $self->{xdb} = $xdb;
         $xdb->begin_transaction;
+        $xdb;
 }
 
 sub commit_txn {
         my ($self) = @_;
-        croak 'BUG: not in txn' unless $self->{xdb}; # XXX make lazy?
-        delete($self->{xdb})->commit_transaction;
+        my $xdb = delete $self->{xdb} or return;
+        $xdb->commit_transaction;
+}
+
+sub create_xdb {
+        my ($self) = @_;
+        $self->{xdb} //= _begin_txn($self);
+        commit_txn($self);
 }
 
 sub remove_eidx_key {
         my ($self, $eidx_key) = @_;
-        my $xdb = $self->{xdb};
+        my $xdb = $self->{xdb} //= _begin_txn($self);
         my $head = $xdb->postlist_begin('Q'.$eidx_key);
         my $tail = $xdb->postlist_end('Q'.$eidx_key);
         my @docids; # only one, unless we had bugs
@@ -74,7 +79,7 @@ sub remove_eidx_key {
 sub index_ibx {
         my ($self, $ibx) = @_;
         my $eidx_key = $ibx->eidx_key;
-        my $xdb = $self->{xdb};
+        my $xdb = $self->{xdb} //= _begin_txn($self);
         # Q = uniQue in Xapian terminology
         my $head = $xdb->postlist_begin('Q'.$eidx_key);
         my $tail = $xdb->postlist_end('Q'.$eidx_key);