From 2e9cf0b63b8de904d6ebca9fb1474cf0f979c53b Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Tue, 11 May 2021 07:43:32 -0600 Subject: [PATCH] Close keepalive connections after MAX_FAST_INLINE requests --- lib/puma/server.rb | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/puma/server.rb b/lib/puma/server.rb index 5b2cd94..4ce0c74 100644 --- a/lib/puma/server.rb +++ b/lib/puma/server.rb @@ -487,15 +487,20 @@ module Puma requests += 1 - check_for_more_data = @status == :run + # Closing keepalive sockets after they've made a reasonable + # number of requests allows Puma to service many connections + # fairly, even when the number of concurrent connections exceeds + # the size of the threadpool. It also allows cluster mode Pumas + # to keep load evenly distributed across workers, because clients + # are randomly assigned a new worker when opening a new connection. + # + # Previously, Puma would kick connections in this conditional back + # to the reactor. However, because this causes the todo set to increase + # in size, the wait_until_full mutex would never unlock, leaving + # any additional connections unserviced. + break if requests >= MAX_FAST_INLINE - if requests >= MAX_FAST_INLINE - # This will mean that reset will only try to use the data it already - # has buffered and won't try to read more data. What this means is that - # every client, independent of their request speed, gets treated like a slow - # one once every MAX_FAST_INLINE requests. - check_for_more_data = false - end + check_for_more_data = @status == :run unless client.reset(check_for_more_data) close_socket = false -- 2.23.0