]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LeiSearch.pm
git: use async_wait_all everywhere
[public-inbox.git] / lib / PublicInbox / LeiSearch.pm
index 9297d060eef8b5e02a27a0a7189b2ac845eb4fe8..4e048e9a40b7a9f2794d067eeef15f750b0d1d61 100644 (file)
@@ -5,10 +5,11 @@
 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);
+use Carp qw(croak);
 
 # get combined docid from over.num:
 # (not generic Xapian, only works with our sharding scheme)
@@ -18,22 +19,22 @@ sub num2docid ($$) {
        ($num - 1) * $nshard + $num % $nshard + 1;
 }
 
-sub msg_keywords {
-       my ($self, $num) = @_; # num_or_mitem
-       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;
+sub _msg_kw { # retry_reopen callback
+       my ($self, $num) = @_;
+       my $xdb = $self->xdb; # set {nshard} for num2docid;
+       xap_terms('K', $xdb, num2docid($self, $num));
 }
 
-# returns undef if blob is unknown
-sub oid_keywords {
-       my ($self, $oidhex) = @_;
-       my @num = $self->over->blob_exists($oidhex) or return;
+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 %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 +42,15 @@ sub oid_keywords {
        \%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});
@@ -62,6 +68,14 @@ 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
+       eval { $self->retry_reopen(\&_xsmsg_vmd, $smsg, $want_label) };
+       warn "$$ $0 (nshard=$self->{nshard}) $smsg->{blob}: $@" if $@;
+}
+
 # when a message has no Message-IDs at all, this is needed for
 # unsent Draft messages, at least
 sub content_key ($) {
@@ -105,24 +119,32 @@ sub xoids_for {
                                $git->cat_async($cur->{blob}, \&_cmp_1st,
                                                [$chash, $xoids, $cur, $lms]);
                                if ($min && scalar(keys %$xoids) >= $min) {
-                                       $git->cat_async_wait;
+                                       $git->async_wait_all;
                                        return $xoids;
                                }
                        }
                }
        }
-       $git->cat_async_wait;
+       $git->async_wait_all;
        scalar(keys %$xoids) ? $xoids : undef;
 }
 
 # 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]);
-
+       my $cur_kw;
+       if ($eml) {
+               my $xoids = xoids_for($self, $eml) // return;
+               $docids //= [];
+               @$docids = sort { $a <=> $b } values %$xoids;
+       }
+       for my $id (@$docids) {
+               $cur_kw = eval { msg_keywords($self, $id) } and last;
+       }
+       if (!defined($cur_kw) && $@) {
+               $docids = join(', num:', @$docids);
+               croak "E: num:$docids keyword lookup failure: $@";
+       }
        # RFC 5550 sec 5.9 on the $Forwarded keyword states:
        # "Once set, the flag SHOULD NOT be cleared"
        if (exists($cur_kw->{forwarded}) &&