about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-06-19 06:55:42 +0000
committerEric Wong <e@80x24.org>2016-06-19 07:04:41 +0000
commit3e792e55f53dd6d31f2f2ff66fa79d9189690294 (patch)
treec69a82e16fe9849acf5e7c24d73597034e3745ff /lib/PublicInbox
parent271301a493f5418ddf5065d412811fde0a68e984 (diff)
downloadpublic-inbox-3e792e55f53dd6d31f2f2ff66fa79d9189690294.tar.gz
This allows us to yield control to other clients gracefully if
getline takes too long to generate a chunk.  This is more
expensive but should not cost a syscall on modern 64-bit systems.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/HTTP.pm7
1 files changed, 5 insertions, 2 deletions
diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm
index e0ed2d15..800b2401 100644
--- a/lib/PublicInbox/HTTP.pm
+++ b/lib/PublicInbox/HTTP.pm
@@ -16,6 +16,7 @@ use Fcntl qw(:seek);
 use Plack::HTTPParser qw(parse_http_request); # XS or pure Perl
 use HTTP::Status qw(status_message);
 use HTTP::Date qw(time2str);
+use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
 use Scalar::Util qw(weaken);
 use IO::File;
 use constant {
@@ -25,6 +26,8 @@ use constant {
         CHUNK_MAX_HDR => 256,
 };
 
+sub now () { clock_gettime(CLOCK_MONOTONIC) }
+
 # FIXME: duplicated code with NNTP.pm, layering violation
 my $WEAKEN = {}; # string(inbox) -> inbox
 my $weakt;
@@ -267,14 +270,14 @@ sub getline_response {
                 my $forward = $self->{forward};
                 # limit our own running time for fairness with other
                 # clients and to avoid buffering too much:
-                my $n = 100;
+                my $end = now() + 0.1;
                 while ($forward && defined(my $buf = $forward->getline)) {
                         $write->($buf);
                         last if $self->{closed};
                         if ($self->{write_buf_size}) {
                                 $self->write($self->{pull});
                                 return;
-                        } elsif ((--$n) <= 0) {
+                        } elsif (now() > $end) {
                                 PublicInbox::EvCleanup::asap($self->{pull});
                                 return;
                         }