]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
solver: use xap_helper for async search if available
authorEric Wong <e@80x24.org>
Thu, 29 Aug 2024 23:26:02 +0000 (23:26 +0000)
committerEric Wong <e@80x24.org>
Sat, 31 Aug 2024 01:10:18 +0000 (01:10 +0000)
The async search API using xap_helper allows -httpd/netd users
to exploit storage and CPU-level parallelism via sockets.  It is
another step towards reducing head-of-line blocking in our Perl
event loop.  This reduces the effect of slow storage and extremely
large search results on unrelated HTTP requests.

lib/PublicInbox/LeiRemote.pm
lib/PublicInbox/SolverGit.pm

index d6fc40a438bbf7361b0c2f07fd95838e0abfa85b..71aef8099e58e9bb6f9d2fdc2e78769b2f3fff27 100644 (file)
@@ -56,6 +56,13 @@ sub mset {
        $self; # we are the mset (and $ibx, and $self)
 }
 
+# fake support for async API
+sub async_mset {
+       my ($self, $qstr, undef, $cb, @arg) = @_; # $opt ($_[2]) ignored
+       $cb->(@arg, mset($self, $qstr));
+       undef;
+}
+
 sub size { scalar @{$_[0]->{smsg}} } # size of previous results
 
 sub mset_to_smsg {
index 4d087eab815cc5dd845c8a1a295bcd230ff9b5d5..6dd222a9ac08c2ebbf2c984cc60a8d8e4eff5dfa 100644 (file)
@@ -128,11 +128,38 @@ sub ck_existing_cb { # async_check cb
        # scan through inboxes to look for emails which results in
        # the oid we want:
        my $ibx = shift(@{$want->{try_ibxs}}) or return done($self, undef);
-       if (my $msgs = find_smsgs($self, $ibx, $want)) {
-               $want->{try_smsgs} = $msgs;
-               $want->{cur_ibx} = $ibx;
-               $self->{tmp_diffs} = [];
-               return retry_current($self, $want);
+
+       # maybe another inbox has it
+       my $srch = $ibx->isrch or return try_harder($self, $want);
+
+       my $post = $want->{oid_b} or die 'BUG: no {oid_b}';
+       $post =~ /\A[a-f0-9]+\z/ or die "BUG: oid_b not hex: $post";
+       my ($q, $pre)= ("dfpost:$post", $want->{oid_a});
+       $q .= " dfpre:$pre" if defined $pre && $pre =~ /\A[a-f0-9]+\z/;
+       my $path_b = $want->{path_b};
+       if (path_searchable($path_b)) {
+               $q .= filename_query($path_b);
+
+               my $path_a = $want->{path_a};
+               (path_searchable($path_a) && $path_a ne $path_b) and
+                       $q .= filename_query($path_a);
+       }
+       $srch->async_mset($q, { relevance => 1 },
+                       \&find_results, $self, $want, $ibx);
+}
+
+sub find_results { # async_mset cb
+       my ($self, $want, $ibx, $mset, $exc) = @_;
+       if ($mset && $mset->size) {
+               if (my $srch = $ibx->isrch) {
+                       my $msgs = $srch->mset_to_smsg($ibx, $mset);
+                       $want->{try_smsgs} = $msgs;
+                       $want->{cur_ibx} = $ibx;
+                       $self->{tmp_diffs} = [];
+                       return retry_current($self, $want);
+               }
+               my $dir = $ibx->{inboxdir} // $ibx->{topdir};
+               warn 'W: ', $dir, " search disappeared, skipping\n";
        }
        try_harder($self, $want);
 }
@@ -275,28 +302,6 @@ sub filename_query ($) {
 
 sub find_smsgs ($$$) {
        my ($self, $ibx, $want) = @_;
-       my $srch = $ibx->isrch or return;
-
-       my $post = $want->{oid_b} or die 'BUG: no {oid_b}';
-       $post =~ /\A[a-f0-9]+\z/ or die "BUG: oid_b not hex: $post";
-
-       my $q = "dfpost:$post";
-       my $pre = $want->{oid_a};
-       if (defined $pre && $pre =~ /\A[a-f0-9]+\z/) {
-               $q .= " dfpre:$pre";
-       }
-
-       my $path_b = $want->{path_b};
-       if (path_searchable($path_b)) {
-               $q .= filename_query($path_b);
-
-               my $path_a = $want->{path_a};
-               if (path_searchable($path_a) && $path_a ne $path_b) {
-                       $q .= filename_query($path_a);
-               }
-       }
-       my $mset = $srch->mset($q, { relevance => 1 });
-       $mset->size ? $srch->mset_to_smsg($ibx, $mset) : undef;
 }
 
 sub update_index_result ($$) {