File tree 2 files changed +22
-1
lines changed
2 files changed +22
-1
lines changed Original file line number Diff line number Diff line change @@ -118,6 +118,13 @@ module Const
118
118
# sending data back
119
119
WRITE_TIMEOUT = 10
120
120
121
+ # How many requests to attempt inline before sending a client back to
122
+ # the reactor to be subject to normal ordering. The idea here is that
123
+ # we amortize the cost of going back to the reactor for a well behaved
124
+ # but very "greedy" client across 10 requests. This prevents a not
125
+ # well behaved client from monopolizing the thread forever.
126
+ MAX_FAST_INLINE = 10
127
+
121
128
# The original URI requested by the client.
122
129
REQUEST_URI = 'REQUEST_URI' . freeze
123
130
REQUEST_PATH = 'REQUEST_PATH' . freeze
Original file line number Diff line number Diff line change @@ -466,6 +466,8 @@ def process_client(client, buffer)
466
466
clean_thread_locals = @options [ :clean_thread_locals ]
467
467
close_socket = true
468
468
469
+ requests = 0
470
+
469
471
while true
470
472
case handle_request ( client , buffer )
471
473
when false
@@ -479,7 +481,19 @@ def process_client(client, buffer)
479
481
480
482
ThreadPool . clean_thread_locals if clean_thread_locals
481
483
482
- unless client . reset ( @status == :run )
484
+ requests += 1
485
+
486
+ check_for_more_data = @status == :run
487
+
488
+ if requests >= MAX_FAST_INLINE
489
+ # This will mean that reset will only try to use the data it already
490
+ # has buffered and won't try to read more data. What this means is that
491
+ # every client, independent of their request speed, gets treated like a slow
492
+ # one once every MAX_FAST_INLINE requests.
493
+ check_for_more_data = false
494
+ end
495
+
496
+ unless client . reset ( check_for_more_data )
483
497
close_socket = false
484
498
client . set_timeout @persistent_timeout
485
499
@reactor . add client
You can’t perform that action at this time.
0 commit comments