user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 2/3] git-http-backend: start refactoring to use callback
  2016-02-25  4:02  6% [PATCH 0/3] migrate git-http-backend to async use Eric Wong
@ 2016-02-25  4:02  7% ` Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2016-02-25  4:02 UTC (permalink / raw)
  To: meta

Designing for asynchronous, non-blocking operations makes
adapting for synchronous, blocking operation easy.

Going the other way around is not easy, so do it now and
allow us to be more easily adapted for non-blocking use
in the next commit...
---
 lib/PublicInbox/GitHTTPBackend.pm | 73 +++++++++++++++++++++++++--------------
 1 file changed, 47 insertions(+), 26 deletions(-)

diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm
index cba025e..3cf7857 100644
--- a/lib/PublicInbox/GitHTTPBackend.pm
+++ b/lib/PublicInbox/GitHTTPBackend.pm
@@ -178,34 +178,55 @@ sub serve_smart {
 		my @cmd = qw(git http-backend);
 		exec(@cmd) or die 'exec `' . join(' ', @cmd). "' failed: $!\n";
 	}
-	$wpipe = undef;
-	$in = undef;
-	my @h;
-	my $code = 200;
-	{
-		local $/ = "\r\n";
-		while (defined(my $line = <$rpipe>)) {
-			if ($line =~ /\AStatus:\s*(\d+)/) {
-				$code = $1;
-			} else {
-				chomp $line;
-				last if $line eq '';
-				push @h, split(/:\s*/, $line, 2);
-			}
+	$wpipe = $in = undef;
+	$rpipe->blocking(0);
+	$buf = '';
+	my $vin;
+	vec($vin, fileno($rpipe), 1) = 1;
+	my ($fh, $res);
+	my $fail = sub {
+		my ($e) = @_;
+		if ($e eq 'EAGAIN') {
+			select($vin, undef, undef, undef);
+		} else {
+			$rpipe = undef;
+			$fh->close if $fh;
+			$err->print('git http-backend error: ', $e, "\n");
 		}
-	}
-	return if $code == 403;
-	sub {
-		my ($cb) = @_;
-		my $fh = $cb->([ $code, \@h ]);
-		while (1) {
-			my $r = sysread($rpipe, $buf, 8192);
-			die "$!\n" unless defined $r;
-			last if ($r == 0);
-			$fh->write($buf);
+	};
+	my $cb = sub {
+		my $r = sysread($rpipe, $buf, 8192, length($buf));
+		return $fail->($!{EAGAIN} ? 'EAGAIN' : $!) unless defined $r;
+		if ($r == 0) { # EOF
+			$rpipe = undef;
+			$fh->close if $fh;
+			return;
 		}
-		$fh->close;
-	}
+		if ($fh) { # stream body from git-http-backend to HTTP client
+			$fh->write($buf);
+			$buf = '';
+		} elsif ($buf =~ s/\A(.*?)\r?\n\r?\n//s) { # parse headers
+			my $h = $1;
+			my $code = 200;
+			my @h;
+			foreach my $l (split(/\r?\n/, $h)) {
+				my ($k, $v) = split(/:\s*/, $l, 2);
+				if ($k =~ /\AStatus\z/i) {
+					$code = int($v);
+				} else {
+					push @h, $k, $v;
+				}
+			}
+			# write response header:
+			$fh = $res->([ $code, \@h ]);
+			$fh->write($buf);
+			$buf = '';
+		} # else { keep reading ... }
+	};
+	sub {
+		($res) = @_;
+		while ($rpipe) { $cb->() }
+	};
 }
 
 1;
-- 
EW


^ permalink raw reply related	[relevance 7%]

* [PATCH 0/3] migrate git-http-backend to async use
@ 2016-02-25  4:02  6% Eric Wong
  2016-02-25  4:02  7% ` [PATCH 2/3] git-http-backend: start refactoring to use callback Eric Wong
  0 siblings, 1 reply; 2+ results
From: Eric Wong @ 2016-02-25  4:02 UTC (permalink / raw)
  To: meta

git-http-backend (and likely other operations) can take a while
before it returns data.  Do not block synchrously on it.

Eric Wong (3):
      use pipe for git-http-backend output
      git-http-backend: start refactoring to use callback
      git-http-backend: start async API for streaming

 lib/PublicInbox/GitHTTPBackend.pm | 90 +++++++++++++++++++++++++--------------
 public-inbox-httpd                | 31 ++++++++++++++
 2 files changed, 88 insertions(+), 33 deletions(-)


^ permalink raw reply	[relevance 6%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2016-02-25  4:02  6% [PATCH 0/3] migrate git-http-backend to async use Eric Wong
2016-02-25  4:02  7% ` [PATCH 2/3] git-http-backend: start refactoring to use callback Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).