From 231c19b5c925f1fd40910508a17d370352710e8d Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 21 May 2016 23:45:27 +0000 Subject: http: support async_pass for Danga::Socket This will allow us to minimize buffering after we wait (possibly a long time) for readability. This also greatly reduces the amount of Danga::Socket-specific knowledge we have in our PSGI code, making it easier for others to understand. --- lib/PublicInbox/HTTP.pm | 18 ++++++++++++++++++ lib/PublicInbox/HTTPD/Async.pm | 2 ++ 2 files changed, 20 insertions(+) (limited to 'lib') diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm index f69056f8..d523bd42 100644 --- a/lib/PublicInbox/HTTP.pm +++ b/lib/PublicInbox/HTTP.pm @@ -219,6 +219,24 @@ sub response_write { if (ref $body eq 'ARRAY') { $write->($_) foreach @$body; $close->(); + } elsif ($body->can('async_pass')) { # HTTPD::Async + # prevent us from reading the body faster than we + # can write to the client + my $restart_read = sub { $body->watch_read(1) }; + $body->async_pass(sub { + local $/ = \8192; + my $buf = $body->getline; + if (defined $buf) { + $write->($buf); + if ($self->{write_buf}) { + $body->watch_read(0); + $self->write($restart_read); + } + return; # continue waiting + } + $body->close; + $close->(); + }); } else { my $pull; $pull = sub { diff --git a/lib/PublicInbox/HTTPD/Async.pm b/lib/PublicInbox/HTTPD/Async.pm index bedb397d..ceba738e 100644 --- a/lib/PublicInbox/HTTPD/Async.pm +++ b/lib/PublicInbox/HTTPD/Async.pm @@ -21,10 +21,12 @@ sub new { $self; } +sub async_pass { $_[0]->{cb} = $_[1] } sub event_read { $_[0]->{cb}->() } sub event_hup { $_[0]->{cb}->() } sub event_err { $_[0]->{cb}->() } sub sysread { shift->{sock}->sysread(@_) } +sub getline { $_[0]->{sock}->getline }; sub close { my $self = shift; -- cgit v1.2.3-24-ge0c7