about summary refs log tree commit homepage
path: root/lib/PublicInbox/ViewVCS.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-01-22 02:10:13 +0000
committerEric Wong <e@80x24.org>2019-01-26 23:57:28 +0000
commitfffbc9ec32b78731acd30539f6e3f2778d2d1fb2 (patch)
tree1d24f8afa85cc21cd9ebc4e9dfd6c1769b0769c7 /lib/PublicInbox/ViewVCS.pm
parenta817e10a4f94270d064fee0f18328efb910d9c35 (diff)
downloadpublic-inbox-fffbc9ec32b78731acd30539f6e3f2778d2d1fb2.tar.gz
solver: rewrite to use Qspawn->psgi_qx and pi-httpd.async
The psgi_qx routine in the now-abandoned "repobrowse" branch
allows us to break down blob-solving at each process execution
point.  It reuses the Qspawn facility for git-http-backend(1),
allowing us to limit parallel subprocesses independently of Perl
worker count.

This is actually a 2-3% slower a fully-synchronous execution;
but it is fair to other clients as it won't monopolize the server
for hundreds of milliseconds (or even seconds) at a time.
Diffstat (limited to 'lib/PublicInbox/ViewVCS.pm')
-rw-r--r--lib/PublicInbox/ViewVCS.pm51
1 files changed, 34 insertions, 17 deletions
diff --git a/lib/PublicInbox/ViewVCS.pm b/lib/PublicInbox/ViewVCS.pm
index 4a3896d4..fa76086a 100644
--- a/lib/PublicInbox/ViewVCS.pm
+++ b/lib/PublicInbox/ViewVCS.pm
@@ -27,37 +27,33 @@ my $enc_utf8 = find_encoding('UTF-8');
 
 sub html_page ($$$) {
         my ($ctx, $code, $strref) = @_;
+        my $wcb = delete $ctx->{-wcb};
         $ctx->{-upfx} = '../../'; # from "/$INBOX/$OID/s/"
-        PublicInbox::WwwStream->response($ctx, $code, sub {
+        my $res = PublicInbox::WwwStream->response($ctx, $code, sub {
                 my ($nr, undef) =  @_;
                 $nr == 1 ? $$strref : undef;
         });
+        $wcb->($res);
 }
 
-sub show ($$;$) {
-        my ($ctx, $oid_b, $fn) = @_;
-        my $ibx = $ctx->{-inbox};
-        my $inboxes = [ $ibx ];
-        my $solver = PublicInbox::SolverGit->new($ibx->{-repo_objs}, $inboxes);
-        my $qp = $ctx->{qp};
-        my $hints = {};
-        while (my ($from, $to) = each %QP_MAP) {
-                defined(my $v = $qp->{$from}) or next;
-                $hints->{$to} = $v;
-        }
-
-        open my $log, '+>', undef or die "open: $!";
-        my $res = $solver->solve($log, $oid_b, $hints);
+sub solve_result {
+        my ($ctx, $res, $log, $hints, $fn) = @_;
 
-        seek($log, 0, 0) or die "seek: $!";
+        unless (seek($log, 0, 0)) {
+                $ctx->{env}->{'psgi.errors'}->print("seek(log): $!\n");
+                return html_page($ctx, 500, \'seek error');
+        }
         $log = do { local $/; <$log> };
 
+        my $ref = ref($res);
+        $log .= $res unless $ref;
         my $l = PublicInbox::Linkify->new;
         $l->linkify_1($log);
         $log = '<pre>debug log:</pre><hr /><pre>' .
                 $l->linkify_2(ascii_html($log)) . '</pre>';
 
         $res or return html_page($ctx, 404, \$log);
+        $ref eq 'ARRAY' or return html_page($ctx, 500, \$log);
 
         my ($git, $oid, $type, $size, $di) = @$res;
         if ($size > $max_size) {
@@ -78,7 +74,7 @@ sub show ($$;$) {
         if ($fn) {
                 my $h = [ 'Content-Length', $size, 'Content-Type' ];
                 push(@$h, ($binary ? 'application/octet-stream' : 'text/plain'));
-                return [ 200, $h, [ $$blob ]];
+                return delete($ctx->{-wcb})->([200, $h, [ $$blob ]]);
         }
 
         my $path = to_filename($di->{path_b} || $hints->{path_b} || 'blob');
@@ -107,4 +103,25 @@ sub show ($$;$) {
         html_page($ctx, 200, \$log);
 }
 
+sub show ($$;$) {
+        my ($ctx, $oid_b, $fn) = @_;
+        my $qp = $ctx->{qp};
+        my $hints = {};
+        while (my ($from, $to) = each %QP_MAP) {
+                defined(my $v = $qp->{$from}) or next;
+                $hints->{$to} = $v;
+        }
+
+        open my $log, '+>', undef or die "open: $!";
+        my $solver = PublicInbox::SolverGit->new($ctx->{-inbox}, sub {
+                solve_result($ctx, $_[0], $log, $hints, $fn);
+        });
+
+        # PSGI server will call this and give us a callback
+        sub {
+                $ctx->{-wcb} = $_[0]; # HTTP write callback
+                $solver->solve($ctx->{env}, $log, $oid_b, $hints);
+        };
+}
+
 1;