diff options
author | Eric Wong <e@80x24.org> | 2016-05-30 04:39:57 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-05-30 04:46:23 +0000 |
commit | 56692b57c4e6a404fee0ec8eef857f35e09ce767 (patch) | |
tree | ba5a3c77f8995122110fa18780b47cad5618c81b | |
parent | 1cf14fe543ad6259003cdd1995a1c83a7a70b535 (diff) | |
download | public-inbox-56692b57c4e6a404fee0ec8eef857f35e09ce767.tar.gz |
http: yield body->getline running time
We cannot let a client monopolize the single-threaded server even if it can drain the socket buffer faster than we can emit data. While we're at it, acknowledge the this behavior (which happens naturally) in httpd/async. The same idea is present in NNTP for the long_response code. This is the HTTP followup to: commit 0d0fde0bff97 ("nntp: introduce long response API for streaming") commit 79d8bfedcdd2 ("nntp: avoid signals for long responses")
-rw-r--r-- | lib/PublicInbox/HTTP.pm | 5 | ||||
-rw-r--r-- | lib/PublicInbox/HTTPD/Async.pm | 4 |
2 files changed, 7 insertions, 2 deletions
diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm index fcbd758a..6df1c3fc 100644 --- a/lib/PublicInbox/HTTP.pm +++ b/lib/PublicInbox/HTTP.pm @@ -265,10 +265,13 @@ sub getline_response { my $pull = $self->{pull} = sub { local $/ = \8192; my $forward = $self->{forward}; + # limit our own running time for fairness with other + # clients and to avoid buffering too much: + my $n = 100; while ($forward && defined(my $buf = $forward->getline)) { $write->($buf); last if $self->{closed}; - if ($self->{write_buf_size}) { + if ((--$n) <= 0 || $self->{write_buf_size}) { $self->write($self->{pull}); return; } diff --git a/lib/PublicInbox/HTTPD/Async.pm b/lib/PublicInbox/HTTPD/Async.pm index add07ce4..fadf2d3a 100644 --- a/lib/PublicInbox/HTTPD/Async.pm +++ b/lib/PublicInbox/HTTPD/Async.pm @@ -45,7 +45,9 @@ sub async_pass { $self->watch_read(0); $io->write($restart_read); # D::S::write } - return; # stay in watch_read + # stay in watch_read, but let other clients + # get some work done, too. + return; } elsif (!defined $r) { return if $!{EAGAIN} || $!{EINTR}; } |