]> Sergey Matveev's repositories - public-inbox.git/commitdiff
searchidxshard: ensure we set indexlevel on shard[0]
authorEric Wong <e@yhbt.net>
Sat, 28 Mar 2020 00:56:03 +0000 (00:56 +0000)
committerEric Wong <e@yhbt.net>
Sun, 29 Mar 2020 23:28:28 +0000 (23:28 +0000)
For sharded v2 repositories with few-enough messages, it is
possible for shard[0] to go unused and never trigger the
->commit_txn_lazy to set the indexlevel field in Xapian
metadata.

So set it immediately at initialization and avoid this case.
While we're at it, avoid triggering needless pwrite syscalls
from ->set_metadata by checking with ->get_metadata, first.

lib/PublicInbox/SearchIdx.pm
lib/PublicInbox/SearchIdxShard.pm
t/init.t

index 44b05813f9a43e371068071ac9b2b666c275d555..7d089e7aee4271645ae562ccf1b13ab24f6d68f7 100644 (file)
@@ -58,6 +58,7 @@ sub new {
                ibx_ver => $version,
                indexlevel => $indexlevel,
        }, $class;
+       $self->{-set_indexlevel_once} = 1 if $indexlevel eq 'medium';
        $ibx->umask_prepare;
        if ($version == 1) {
                $self->{lock_path} = "$inboxdir/ssoma.lock";
@@ -842,20 +843,27 @@ sub begin_txn_lazy {
        });
 }
 
+# store 'indexlevel=medium' in v2 shard=0 and v1 (only one shard)
+# This metadata is read by Admin::detect_indexlevel:
+sub set_indexlevel {
+       my ($self) = @_;
+
+       if (!$self->{shard} && # undef or 0, not >0
+                       delete($self->{-set_indexlevel_once})) {
+               my $xdb = $self->{xdb};
+               my $level = $xdb->get_metadata('indexlevel');
+               if (!$level || $level ne 'medium') {
+                       $xdb->set_metadata('indexlevel', 'medium');
+               }
+       }
+}
+
 sub commit_txn_lazy {
        my ($self) = @_;
        delete $self->{txn} or return;
        $self->{-inbox}->with_umask(sub {
                if (my $xdb = $self->{xdb}) {
-
-                       # store 'indexlevel=medium' in v2 shard=0 and
-                       # v1 (only one shard)
-                       # This metadata is read by Admin::detect_indexlevel:
-                       if (!$self->{shard} # undef or 0, not >0
-                           && $self->{indexlevel} eq 'medium') {
-                               $xdb->set_metadata('indexlevel', 'medium');
-                       }
-
+                       set_indexlevel($self);
                        $xdb->commit_transaction;
                }
                $self->{over}->commit_lazy if $self->{over};
index 2b48b1b4154444552a8b144709d0e144447eb068..1ea01095c4fa6829fd6dc914cefdb0da3dc23f24 100644 (file)
@@ -11,9 +11,11 @@ use IO::Handle (); # autoflush
 
 sub new {
        my ($class, $v2writable, $shard) = @_;
-       my $self = $class->SUPER::new($v2writable->{-inbox}, 1, $shard);
+       my $ibx = $v2writable->{-inbox};
+       my $self = $class->SUPER::new($ibx, 1, $shard);
        # create the DB before forking:
        $self->_xdb_acquire;
+       $self->set_indexlevel;
        $self->_xdb_release;
        $self->spawn_worker($v2writable, $shard) if $v2writable->{parallel};
        $self;
index e20ff006126bb27d2730d2ed4a7667e3e2bb325e..a78c2fc868a13da125cc29f2567559238224a796 100644 (file)
--- a/t/init.t
+++ b/t/init.t
@@ -5,6 +5,7 @@ use warnings;
 use Test::More;
 use PublicInbox::Config;
 use PublicInbox::TestCommon;
+use PublicInbox::Admin;
 use File::Basename;
 my ($tmpdir, $for_destroy) = tmpdir();
 sub quiet_fail {
@@ -72,11 +73,15 @@ SKIP: {
        quiet_fail($cmd, 'initializing V2 as V1 fails');
 
        foreach my $lvl (qw(medium basic)) {
+               my $dir = "$tmpdir/v2$lvl";
                $cmd = [ '-init', "v2$lvl", '-V2', '-L', $lvl,
-                       "$tmpdir/v2$lvl", "http://example.com/v2$lvl",
+                       $dir, "http://example.com/v2$lvl",
                        "v2$lvl\@example.com" ];
                ok(run_script($cmd), "-init -L $lvl");
                is(read_indexlevel("v2$lvl"), $lvl, "indexlevel set to '$lvl'");
+               my $ibx = PublicInbox::Inbox->new({ inboxdir => $dir });
+               is(PublicInbox::Admin::detect_indexlevel($ibx), $lvl,
+                       'detected expected level w/o config');
        }
 
        # loop for idempotency