diff options
author | Eric Wong <e@80x24.org> | 2016-05-21 23:45:27 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-05-21 23:46:06 +0000 |
commit | 231c19b5c925f1fd40910508a17d370352710e8d (patch) | |
tree | 81cbc756da39cfde0760b3dde94b81b0e510a964 | |
parent | 7b894cec6bed52cb0ad60d87447cd9e0f7efd0c6 (diff) | |
download | public-inbox-231c19b5c925f1fd40910508a17d370352710e8d.tar.gz |
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.
-rw-r--r-- | lib/PublicInbox/HTTP.pm | 18 | ||||
-rw-r--r-- | lib/PublicInbox/HTTPD/Async.pm | 2 |
2 files changed, 20 insertions, 0 deletions
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; |