]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LeiSearch.pm
www_stream: extra link to mirroring information in the footer
[public-inbox.git] / lib / PublicInbox / LeiSearch.pm
index fb19229fa868bc11f2d3228b74f17c19b2bb19d8..47160ed98b7a81a4988cd9187fb8afd55a177217 100644 (file)
@@ -5,7 +5,7 @@
 package PublicInbox::LeiSearch;
 use strict;
 use v5.10.1;
-use parent qw(PublicInbox::ExtSearch);
+use parent qw(PublicInbox::ExtSearch); # PublicInbox::Search->reopen
 use PublicInbox::Search qw(xap_terms);
 use PublicInbox::ContentHash qw(content_digest content_hash);
 use PublicInbox::MID qw(mids mids_for_index);
@@ -18,36 +18,66 @@ sub num2docid ($$) {
        ($num - 1) * $nshard + $num % $nshard + 1;
 }
 
-sub msg_keywords {
-       my ($self, $num) = @_; # num_or_mitem
+sub _msg_kw { # retry_reopen callback
+       my ($self, $num) = @_;
+       my $xdb = $self->xdb; # set {nshard} for num2docid;
+       xap_terms('K', $xdb, num2docid($self, $num));
+}
+
+sub msg_keywords { # array or hashref
+       my ($self, $num) = @_;
+       $self->retry_reopen(\&_msg_kw, $num);
+}
+
+sub _oid_kw { # retry_reopen callback
+       my ($self, $nums) = @_;
        my $xdb = $self->xdb; # set {nshard};
-       my $docid = ref($num) ? $num->get_docid : num2docid($self, $num);
-       my $kw = xap_terms('K', $xdb, $docid);
-       warn "E: #$docid ($num): $@\n" if $@;
-       wantarray ? sort(keys(%$kw)) : $kw;
+       my %kw;
+       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);
+       }
+       \%kw;
 }
 
-# lookup keywords+labels for external messages
-sub xsmsg_vmd {
+# returns undef if blob is unknown
+sub oidbin_keywords {
+       my ($self, $oidbin) = @_;
+       my @num = $self->over->oidbin_exists($oidbin) 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});
        my @num = $self->over->blob_exists($smsg->{blob});
        for my $num (@num) { # there should only be one...
-               $doc = $xdb->get_document(num2docid($self, $num));
-               $x = xap_terms('K', $doc);
-               %kw = (%kw, %$x);
-               if ($want_label) { # JSON/JMAP only
-                       $x = xap_terms('L', $doc);
-                       %L = (%L, %$x);
-               }
+               eval {
+                       $doc = $xdb->get_document(num2docid($self, $num));
+                       $x = xap_terms('K', $doc);
+                       %kw = (%kw, %$x);
+                       if ($want_label) { # JSON/JMAP only
+                               $x = xap_terms('L', $doc);
+                               %L = (%L, %$x);
+                       }
+               };
+               warn "$$ $0 #$num (nshard=$self->{nshard}) $smsg->{blob}: $@"
+                       if $@;
        }
        $smsg->{kw} = [ sort keys %kw ] if scalar(keys(%kw));
        $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 ($) {
@@ -104,10 +134,13 @@ sub xoids_for {
 # returns true if $eml is indexed by lei/store and keywords don't match
 sub kw_changed {
        my ($self, $eml, $new_kw_sorted, $docids) = @_;
-       my $xoids = xoids_for($self, $eml) // return;
-       $docids //= [];
-       @$docids = sort { $a <=> $b } values %$xoids;
-       my $cur_kw = msg_keywords($self, $docids->[0]);
+       if ($eml) {
+               my $xoids = xoids_for($self, $eml) // return;
+               $docids //= [];
+               @$docids = sort { $a <=> $b } values %$xoids;
+       }
+       my $cur_kw = eval { msg_keywords($self, $docids->[0]) };
+       die "E: #$docids->[0] keyword lookup failure: $@\n" if $@;
 
        # RFC 5550 sec 5.9 on the $Forwarded keyword states:
        # "Once set, the flag SHOULD NOT be cleared"