about summary refs log tree commit homepage
path: root/lib/PublicInbox/LeiSearch.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-05-28 19:47:23 +0000
committerEric Wong <e@80x24.org>2021-05-28 22:37:53 +0000
commit5944277a4dc986f9adf9ba69a1e6e44899ad98c1 (patch)
tree45c8fe978d381e61eb3e7658ef89fa51f7a2103d /lib/PublicInbox/LeiSearch.pm
parent82e141cdf4a00de174b0a919689d846bb387cbf5 (diff)
downloadpublic-inbox-5944277a4dc986f9adf9ba69a1e6e44899ad98c1.tar.gz
Xapian DBs may be modified by a parallel process while we're
reading it, and Xapian's MVCC model places the burden on readers
to retry operations.

We'll also have retry_reopen croak instead of die on errors,
which ought to help us track down some "Document not found"
errors I've occasionally seen when using "lei <q|up>".
Diffstat (limited to 'lib/PublicInbox/LeiSearch.pm')
-rw-r--r--lib/PublicInbox/LeiSearch.pm33
1 files changed, 24 insertions, 9 deletions
diff --git a/lib/PublicInbox/LeiSearch.pm b/lib/PublicInbox/LeiSearch.pm
index 9297d060..b09d1e45 100644
--- a/lib/PublicInbox/LeiSearch.pm
+++ b/lib/PublicInbox/LeiSearch.pm
@@ -18,7 +18,7 @@ sub num2docid ($$) {
         ($num - 1) * $nshard + $num % $nshard + 1;
 }
 
-sub msg_keywords {
+sub _msg_kw { # retry_reopen callback
         my ($self, $num) = @_; # num_or_mitem
         my $xdb = $self->xdb; # set {nshard};
         my $docid = ref($num) ? $num->get_docid : num2docid($self, $num);
@@ -27,13 +27,16 @@ sub msg_keywords {
         wantarray ? sort(keys(%$kw)) : $kw;
 }
 
-# returns undef if blob is unknown
-sub oid_keywords {
-        my ($self, $oidhex) = @_;
-        my @num = $self->over->blob_exists($oidhex) or return;
+sub msg_keywords {
+        my ($self, $num) = @_; # num_or_mitem
+        $self->retry_reopen(\&_msg_kw, $num);
+}
+
+sub _oid_kw { # retry_reopen callback
+        my ($self, $nums) = @_;
         my $xdb = $self->xdb; # set {nshard};
         my %kw;
-        for my $num (@num) { # there should only be one...
+        for my $num (@$nums) { # there should only be one...
                 my $doc = $xdb->get_document(num2docid($self, $num));
                 my $x = xap_terms('K', $doc);
                 %kw = (%kw, %$x);
@@ -41,10 +44,15 @@ sub oid_keywords {
         \%kw;
 }
 
-# lookup keywords+labels for external messages
-sub xsmsg_vmd {
+# returns undef if blob is unknown
+sub oid_keywords {
+        my ($self, $oidhex) = @_;
+        my @num = $self->over->blob_exists($oidhex) or return;
+        $self->retry_reopen(\&_oid_kw, \@num);
+}
+
+sub _xsmsg_vmd { # retry_reopen
         my ($self, $smsg, $want_label) = @_;
-        return if $smsg->{kw};
         my $xdb = $self->xdb; # set {nshard};
         my (%kw, %L, $doc, $x);
         $kw{flagged} = 1 if delete($smsg->{lei_q_tt_flagged});
@@ -62,6 +70,13 @@ sub xsmsg_vmd {
         $smsg->{L} = [ sort keys %L ] if scalar(keys(%L));
 }
 
+# lookup keywords+labels for external messages
+sub xsmsg_vmd {
+        my ($self, $smsg, $want_label) = @_;
+        return if $smsg->{kw}; # already set by LeiXSearch->mitem_kw
+        $self->retry_reopen(\&_xsmsg_vmd, $smsg, $want_label);
+}
+
 # when a message has no Message-IDs at all, this is needed for
 # unsent Draft messages, at least
 sub content_key ($) {