]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Qspawn.pm
qspawn: import Scalar::Util::blessed properly
[public-inbox.git] / lib / PublicInbox / Qspawn.pm
index ab0ef25c5611f3e645a4f4e593ae143ee94291a6..0044c1f6b818683497120574f917cac8b642de77 100644 (file)
 # processes such as git-apply(1).
 
 package PublicInbox::Qspawn;
-use strict;
-use v5.10.1;
+use v5.12;
 use PublicInbox::Spawn qw(popen_rd);
 use PublicInbox::GzipFilter;
+use Scalar::Util qw(blessed);
 
 # n.b.: we get EAGAIN with public-inbox-httpd, and EINTR on other PSGI servers
 use Errno qw(EAGAIN EINTR);
@@ -109,8 +109,9 @@ sub finalize ($$) {
        return if $self->{passed}; # another command chained it
        if (my $wcb = delete $env->{'qspawn.wcb'}) {
                # have we started writing, yet?
+               my $code = delete $env->{'qspawn.fallback'} // 500;
                require PublicInbox::WwwStatic;
-               $wcb->(PublicInbox::WwwStatic::r(500));
+               $wcb->(PublicInbox::WwwStatic::r($code));
        }
 }
 
@@ -133,7 +134,7 @@ sub start ($$$) {
        }
 }
 
-sub psgi_qx_init_cb {
+sub psgi_qx_init_cb { # this may be PublicInbox::HTTPD::Async {cb}
        my ($self) = @_;
        my $async = delete $self->{async}; # PublicInbox::HTTPD::Async
        my ($r, $buf);
@@ -200,7 +201,7 @@ sub rd_hdr ($) {
        my $total_rd = 0;
        my $hdr_buf = $self->{hdr_buf};
        my ($ph_cb, $ph_arg) = @{$self->{parse_hdr}};
-       do {
+       until (defined($ret)) {
                my $r = sysread($self->{rpipe}, $$hdr_buf, 4096,
                                length($$hdr_buf));
                if (defined($r)) {
@@ -209,6 +210,13 @@ sub rd_hdr ($) {
                        if ($@) {
                                warn "parse_hdr: $@";
                                $ret = [ 500, [], [ "Internal error\n" ] ];
+                       } elsif (!defined($ret) && !$r) {
+                               my $cmd = $self->{cmd} // [ '(?)' ];
+                               my $env = $self->{psgi_env};
+                               warn <<EOM;
+EOF parsing headers from @$cmd ($self->{psgi_env}->{REQUEST_URI})
+EOM
+                               $ret = [ 500, [], [ "Internal error\n" ] ];
                        }
                } else {
                        # caller should notify us when it's ready:
@@ -217,18 +225,19 @@ sub rd_hdr ($) {
                        warn "error reading header: $!";
                        $ret = [ 500, [], [ "Internal error\n" ] ];
                }
-       } until (defined $ret);
+       }
        delete $self->{parse_hdr}; # done parsing headers
        $ret;
 }
 
-sub psgi_return_init_cb {
+sub psgi_return_init_cb { # this may be PublicInbox::HTTPD::Async {cb}
        my ($self) = @_;
        my $r = rd_hdr($self) or return;
        my $env = $self->{psgi_env};
        my $filter;
-       if (ref($r) eq 'ARRAY' && Scalar::Util::blessed($r->[2]) &&
-                       $r->[2]->can('attach')) {
+
+       # this is for RepoAtom since that can fire after parse_cgi_headers
+       if (ref($r) eq 'ARRAY' && blessed($r->[2]) && $r->[2]->can('attach')) {
                $filter = pop @$r;
        }
        $filter //= delete($env->{'qspawn.filter'}) // (ref($r) eq 'ARRAY' ?
@@ -324,8 +333,7 @@ sub psgi_return {
 }
 
 package PublicInbox::Qspawn::Limiter;
-use strict;
-use warnings;
+use v5.12;
 
 sub new {
        my ($class, $max) = @_;