about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-05-21 23:45:27 +0000
committerEric Wong <e@80x24.org>2016-05-21 23:46:06 +0000
commit231c19b5c925f1fd40910508a17d370352710e8d (patch)
tree81cbc756da39cfde0760b3dde94b81b0e510a964 /lib/PublicInbox
parent7b894cec6bed52cb0ad60d87447cd9e0f7efd0c6 (diff)
downloadpublic-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.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/HTTP.pm18
-rw-r--r--lib/PublicInbox/HTTPD/Async.pm2
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;