about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong (Contractor, The Linux Foundation) <e@80x24.org>2018-03-06 07:28:56 +0000
committerEric Wong (Contractor, The Linux Foundation) <e@80x24.org>2018-03-06 07:28:56 +0000
commitcab22861f2a22482b74d20c05afbd6108a4590cb (patch)
tree893cbc6655a0066878105e2b04c35fe5124ab57c
parentfe99e1e4900b5fbe8da4aef25bb0dd05eacb25a3 (diff)
downloadpublic-inbox-cab22861f2a22482b74d20c05afbd6108a4590cb.tar.gz
We need to detect the number of partitions the repository was
created with to ensure Xapian DBs can work across different
machines (or even CPU affinity changes) without leaving messages
unaffected by search.
-rw-r--r--lib/PublicInbox/V2Writable.pm22
-rw-r--r--t/v2writable.t11
2 files changed, 30 insertions, 3 deletions
diff --git a/lib/PublicInbox/V2Writable.pm b/lib/PublicInbox/V2Writable.pm
index 3bcea37d..7728b91a 100644
--- a/lib/PublicInbox/V2Writable.pm
+++ b/lib/PublicInbox/V2Writable.pm
@@ -19,7 +19,9 @@ use PublicInbox::Inbox;
 my $PACKING_FACTOR = 0.4;
 
 # assume 2 cores if GNU nproc(1) is not available
-my $NPROC = int($ENV{NPROC} || `nproc 2>/dev/null` || 2);
+sub nproc () {
+        int($ENV{NPROC} || `nproc 2>/dev/null` || 2);
+}
 
 sub new {
         my ($class, $v2ibx, $creat) = @_;
@@ -32,12 +34,28 @@ sub new {
                         die "$dir does not exist\n";
                 }
         }
+
+        my $nparts = 0;
+        my $xpfx = "$dir/xap" . PublicInbox::Search::SCHEMA_VERSION;
+
+        # always load existing partitions in case core count changes:
+        if (-d $xpfx) {
+                foreach my $part (<$xpfx/*>) {
+                        -d $part && $part =~ m!/\d+\z! or next;
+                        eval {
+                                Search::Xapian::Database->new($part)->close;
+                                $nparts++;
+                        };
+                }
+        }
+        $nparts = nproc() if ($nparts == 0);
+
         my $self = {
                 -inbox => $v2ibx,
                 im => undef, #  PublicInbox::Import
                 xap_rw => undef, # PublicInbox::V2SearchIdx
                 xap_ro => undef,
-                partitions => $NPROC,
+                partitions => $nparts,
                 transact_bytes => 0,
                 # limit each repo to 1GB or so
                 rotate_bytes => int((1024 * 1024 * 1024) / $PACKING_FACTOR),
diff --git a/t/v2writable.t b/t/v2writable.t
index 2d35aca3..404c8651 100644
--- a/t/v2writable.t
+++ b/t/v2writable.t
@@ -30,7 +30,11 @@ my $mime = PublicInbox::MIME->create(
         body => "hello world\n",
 );
 
-my $im = PublicInbox::V2Writable->new($ibx, 1);
+my $im = eval {
+        local $ENV{NPROC} = '1';
+        PublicInbox::V2Writable->new($ibx, 1);
+};
+is($im->{partitions}, 1, 'one partition when forced');
 ok($im->add($mime), 'ordinary message added');
 
 if ('ensure git configs are correct') {
@@ -182,5 +186,10 @@ EOF
         }
         is_deeply([sort keys %nn], [sort keys %uniq]);
 };
+{
+        local $ENV{NPROC} = 2;
+        $im = PublicInbox::V2Writable->new($ibx, 1);
+        is($im->{partitions}, 1, 'detected single partition from previous');
+}
 
 done_testing();