user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 10/30] qspawn: psgi_return_start: hoist out from psgi_return
Date: Wed, 25 Dec 2019 07:50:44 +0000	[thread overview]
Message-ID: <20191225075104.22184-11-e@80x24.org> (raw)
In-Reply-To: <20191225075104.22184-1-e@80x24.org>

Instead of just passing the rpipe to the start_cb, pass the
entire qspawn ref to start_cb.  Update existing callers to
avoid circular refs.
---
 lib/PublicInbox/Qspawn.pm | 41 ++++++++++++++++++++-------------------
 t/qspawn.t                | 19 +++++++++---------
 2 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/lib/PublicInbox/Qspawn.pm b/lib/PublicInbox/Qspawn.pm
index 0967bcfa..33e20147 100644
--- a/lib/PublicInbox/Qspawn.pm
+++ b/lib/PublicInbox/Qspawn.pm
@@ -66,7 +66,7 @@ sub _do_spawn {
 	} else {
 		$self->{err} = $!;
 	}
-	$start_cb->($self->{rpipe});
+	$start_cb->($self);
 }
 
 sub child_err ($) {
@@ -140,7 +140,7 @@ sub finish ($) {
 	}
 }
 
-sub start {
+sub start ($$$) {
 	my ($self, $limiter, $start_cb) = @_;
 	if ($limiter->{running} < $limiter->{max}) {
 		_do_spawn($self, $start_cb, $limiter);
@@ -275,6 +275,17 @@ sub psgi_return_init_cb {
 	$wcb = undef;
 }
 
+sub psgi_return_start { # may run later, much later...
+	my ($self) = @_;
+	if (my $async = $self->{psgi_env}->{'pi-httpd.async'}) {
+		# PublicInbox::HTTPD::Async->new(rpipe, $cb, $cb_arg, $end_obj)
+		$self->{async} = $async->($self->{rpipe},
+					\&psgi_return_init_cb, $self, $self);
+	} else { # generic PSGI
+		psgi_return_init_cb($self) while $self->{parse_hdr};
+	}
+}
+
 # Used for streaming the stdout of one process as a PSGI response.
 #
 # $env is the PSGI env.
@@ -303,30 +314,20 @@ sub psgi_return {
 	$self->{hdr_buf} = \(my $hdr_buf = '');
 	$self->{parse_hdr} = $parse_hdr;
 	$limiter ||= $def_limiter ||= PublicInbox::Qspawn::Limiter->new(32);
-	my $start_cb = sub { # may run later, much later...
-		if (my $async = $env->{'pi-httpd.async'}) {
-			# PublicInbox::HTTPD::Async->new(rpipe, $cb, $cb_arg,
-			#				 $end_obj)
-			$self->{async} = $async->($self->{rpipe},
-						\&psgi_return_init_cb, $self,
-						$self);
-		} else { # generic PSGI
-			psgi_return_init_cb($self) while $self->{parse_hdr};
-		}
-	};
 
 	# the caller already captured the PSGI write callback from
 	# the PSGI server, so we can call ->start, here:
-	return $self->start($limiter, $start_cb) if $env->{'qspawn.wcb'};
+	$env->{'qspawn.wcb'} and
+		return start($self, $limiter, \&psgi_return_start);
 
 	# the caller will return this sub to the PSGI server, so
-	# it can set the response callback (that is, for PublicInbox::HTTP,
-	# the chunked_wcb or identity_wcb callback), but other HTTP servers
-	# are supported:
+	# it can set the response callback (that is, for
+	# PublicInbox::HTTP, the chunked_wcb or identity_wcb callback),
+	# but other HTTP servers are supported:
 	sub {
-		$self->{psgi_env}->{'qspawn.wcb'} = $_[0];
-		$self->start($limiter, $start_cb);
-	};
+		$env->{'qspawn.wcb'} = $_[0];
+		start($self, $limiter, \&psgi_return_start);
+	}
 }
 
 package PublicInbox::Qspawn::Limiter;
diff --git a/t/qspawn.t b/t/qspawn.t
index fc288a2d..8bc88e0e 100644
--- a/t/qspawn.t
+++ b/t/qspawn.t
@@ -23,9 +23,9 @@ my $limiter = PublicInbox::Qspawn::Limiter->new(1);
 	my $x = PublicInbox::Qspawn->new([qw(true)]);
 	my $run = 0;
 	$x->start($limiter, sub {
-		my ($rpipe) = @_;
-		is(0, sysread($rpipe, my $buf, 1), 'read zero bytes');
-		ok(!finish_err($x), 'no error on finish');
+		my ($self) = @_;
+		is(0, sysread($self->{rpipe}, my $buf, 1), 'read zero bytes');
+		ok(!finish_err($self), 'no error on finish');
 		$run = 1;
 	});
 	is($run, 1, 'callback ran alright');
@@ -35,9 +35,10 @@ my $limiter = PublicInbox::Qspawn::Limiter->new(1);
 	my $x = PublicInbox::Qspawn->new([qw(false)]);
 	my $run = 0;
 	$x->start($limiter, sub {
-		my ($rpipe) = @_;
-		is(0, sysread($rpipe, my $buf, 1), 'read zero bytes from false');
-		ok(finish_err($x), 'error on finish');
+		my ($self) = @_;
+		is(0, sysread($self->{rpipe}, my $buf, 1),
+				'read zero bytes from false');
+		ok(finish_err($self), 'error on finish');
 		$run = 1;
 	});
 	is($run, 1, 'callback ran alright');
@@ -47,16 +48,16 @@ foreach my $cmd ([qw(sleep 1)], [qw(sh -c), 'sleep 1; false']) {
 	my $s = PublicInbox::Qspawn->new($cmd);
 	my @run;
 	$s->start($limiter, sub {
-		my ($rpipe) = @_;
+		my ($self) = @_;
 		push @run, 'sleep';
-		is(0, sysread($rpipe, my $buf, 1), 'read zero bytes');
+		is(0, sysread($self->{rpipe}, my $buf, 1), 'read zero bytes');
 	});
 	my $n = 0;
 	my @t = map {
 		my $i = $n++;
 		my $x = PublicInbox::Qspawn->new([qw(true)]);
 		$x->start($limiter, sub {
-			my ($rpipe) = @_;
+			my ($self) = @_;
 			push @run, $i;
 		});
 		[$x, $i]

  parent reply	other threads:[~2019-12-25  7:51 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-25  7:50 [PATCH 00/30] www: eliminate most per-request closures Eric Wong
2019-12-25  7:50 ` [PATCH 01/30] git: allow async_cat to pass arg to callback Eric Wong
2019-12-25  7:50 ` [PATCH 02/30] httpd/async: support passing arg to callbacks Eric Wong
2019-12-26  7:53   ` Eric Wong
2019-12-25  7:50 ` [PATCH 03/30] qspawn: remove some anonymous subs for psgi_qx Eric Wong
2019-12-25  7:50 ` [PATCH 04/30] qspawn: disambiguate command vs PSGI env Eric Wong
2019-12-25  7:50 ` [PATCH 05/30] qspawn: replace anonymous $end callbacks w/ event_step Eric Wong
2019-12-25  7:50 ` [PATCH 06/30] msg_iter: provide means to stop using anonymous subs Eric Wong
2019-12-25  7:50 ` [PATCH 07/30] qspawn: reduce local vars, de-anonymize rd_hdr Eric Wong
2019-12-25  7:50 ` [PATCH 08/30] httpd/async: get rid of ephemeral main_cb Eric Wong
2019-12-25  7:50 ` [PATCH 09/30] qspawn: psgi_return: initial cb can be named Eric Wong
2019-12-25  7:50 ` Eric Wong [this message]
2019-12-25  7:50 ` [PATCH 11/30] qspawn: psgi_qx: eliminate anonymous subs Eric Wong
2019-12-25  7:50 ` [PATCH 12/30] qspawn: drop "qspawn.filter" support, for now Eric Wong
2019-12-25  7:50 ` [PATCH 13/30] qspawn: psgi_return: allow non-anon parse_hdr callback Eric Wong
2019-12-25  7:50 ` [PATCH 14/30] githttpbackend: split out wwwstatic Eric Wong
2019-12-26 12:50   ` Eric Wong
2019-12-27 10:36     ` Eric Wong
2019-12-25  7:50 ` [PATCH 15/30] www: lazy load Plack::Util Eric Wong
2019-12-25  7:50 ` [PATCH 16/30] mboxgz: pass $ctx to callback to avoid anon subs Eric Wong
2019-12-25  7:50 ` [PATCH 17/30] feed: avoid anonymous subs Eric Wong
2019-12-25  7:50 ` [PATCH 18/30] config: each_inbox: pass user arg to callback Eric Wong
2019-12-26  6:48   ` Eric Wong
2019-12-25  7:50 ` [PATCH 19/30] view: avoid anon sub in stream_thread Eric Wong
2019-12-25  7:50 ` [PATCH 20/30] view: msg_html: stop using an anonymous sub Eric Wong
2019-12-25  7:50 ` [PATCH 21/30] contentid: no " Eric Wong
2019-12-25  7:50 ` [PATCH 22/30] wwwtext: avoid anonymous sub in response Eric Wong
2019-12-25  7:50 ` [PATCH 23/30] searchview: pass named subs to Www*Stream Eric Wong
2019-12-25  7:50 ` [PATCH 24/30] view: thread_html: pass named sub to WwwStream Eric Wong
2019-12-25  7:50 ` [PATCH 25/30] searchview: remove anonymous sub when sorting threads by relevance Eric Wong
2019-12-25  7:51 ` [PATCH 26/30] view: msg_iter calls add_body_text directly Eric Wong
2019-12-25  7:51 ` [PATCH 27/30] wwwattach: avoid anonymous sub for msg_iter Eric Wong
2019-12-25  7:51 ` [PATCH 28/30] viewvcs: avoid anonymous sub for HTML response Eric Wong
2019-12-25  7:51 ` [PATCH 29/30] solvergit: allow passing arg to user-supplied callback Eric Wong
2019-12-28  9:17   ` Eric Wong
2019-12-25  7:51 ` [PATCH 30/30] search: retry_reopen passes user arg to callback Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191225075104.22184-11-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).