]> Sergey Matveev's repositories - public-inbox.git/commitdiff
view: /$INBOX/$MSGID/t/ reads blobs asynchronously
authorEric Wong <e@yhbt.net>
Sun, 5 Jul 2020 23:27:45 +0000 (23:27 +0000)
committerEric Wong <e@yhbt.net>
Mon, 6 Jul 2020 20:01:15 +0000 (20:01 +0000)
Once again, this shows a ~10% speedup with multi-message
threads in xt/httpd-async-stream.t regardless of whether
TEST_JOBS is 1 or 100.

lib/PublicInbox/View.pm

index 98445f0e0b0f60ad0a1ee07b28fb4b3fe1dec19b..117257a64ff5222fdf0b5e54ca6cd9e2f1c32a08 100644 (file)
@@ -375,7 +375,7 @@ sub thread_eml_entry {
        $beg . '<pre>' . eml_entry($ctx, $smsg, $eml, 0) . '</pre>' . $end;
 }
 
-sub next_in_queue ($;$) {
+sub next_in_queue ($$) {
        my ($q, $ghost_ok) = @_;
        while (@$q) {
                my ($level, $smsg) = splice(@$q, 0, 2);
@@ -387,29 +387,39 @@ sub next_in_queue ($;$) {
 }
 
 sub stream_thread_i { # PublicInbox::WwwStream::getline callback
-       my ($ctx) = @_;
-       return unless exists($ctx->{skel});
-       my $nr = $ctx->{nr}++;
-       my ($level, $smsg) = next_in_queue($ctx->{-queue}, $nr);
-
-       $smsg or return
-               join('', thread_adj_level($ctx, 0)) . ${delete $ctx->{skel}};
-
-       my $eml = $ctx->{-inbox}->smsg_eml($smsg) or return
-               ghost_index_entry($ctx, $level, $smsg);
+       my ($ctx, $eml) = @_;
 
-       if ($nr == 0) {
-               $ctx->{-title_html} = ascii_html($smsg->{subject});
-               $ctx->html_top . thread_eml_entry($ctx, $level, $smsg, $eml);
-       } else {
-               thread_eml_entry($ctx, $level, $smsg, $eml);
+       if ($eml) {
+               my ($level, $smsg) = delete @$ctx{qw(level smsg)};
+               if ($ctx->{nr} == 1) {
+                       $ctx->{-title_html} = ascii_html($smsg->{subject});
+                       $ctx->zmore($ctx->html_top);
+               }
+               return thread_eml_entry($ctx, $level, $smsg, $eml);
+       }
+       return unless exists($ctx->{skel});
+       my $ghost_ok = $ctx->{nr}++;
+       while (1) {
+               my ($lvl, $smsg) = next_in_queue($ctx->{-queue}, $ghost_ok);
+               if ($smsg) {
+                       if (exists $smsg->{blob}) { # next message for cat-file
+                               $ctx->{level} = $lvl;
+                               return $smsg;
+                       }
+                       # buffer the ghost entry and loop
+                       $ctx->zmore(ghost_index_entry($ctx, $lvl, $smsg));
+               } else { # all done
+                       $ctx->zmore(join('', thread_adj_level($ctx, 0)));
+                       $ctx->zmore(${delete($ctx->{skel})});
+                       return;
+               }
        }
 }
 
 sub stream_thread ($$) {
        my ($rootset, $ctx) = @_;
        $ctx->{-queue} = [ map { (0, $_) } @$rootset ];
-       PublicInbox::WwwStream::response($ctx, 200, \&stream_thread_i);
+       PublicInbox::WwwStream::aresponse($ctx, 200, \&stream_thread_i);
 }
 
 # /$INBOX/$MESSAGE_ID/t/