diff --git a/lib/puma/client.rb b/lib/puma/client.rb index 3a0b98dcc8..0741107af7 100644 --- a/lib/puma/client.rb +++ b/lib/puma/client.rb @@ -162,7 +162,7 @@ def close begin @io.close rescue IOError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue end end diff --git a/lib/puma/cluster/worker.rb b/lib/puma/cluster/worker.rb index 53720f4d37..07368fd7c0 100644 --- a/lib/puma/cluster/worker.rb +++ b/lib/puma/cluster/worker.rb @@ -106,7 +106,7 @@ def run begin @worker_write << "b#{Process.pid}:#{index}\n" rescue SystemCallError, IOError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue STDERR.puts "Master seems to have exited, exiting." return end @@ -127,7 +127,7 @@ def run payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads": #{m}, "requests_count": #{rc} }\n! io << payload rescue IOError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue break end sleep Const::WORKER_CHECK_INTERVAL diff --git a/lib/puma/minissl.rb b/lib/puma/minissl.rb index 77d57a5ba4..9f1bc81854 100644 --- a/lib/puma/minissl.rb +++ b/lib/puma/minissl.rb @@ -169,7 +169,7 @@ def close end end rescue IOError, SystemCallError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue # nothing ensure @socket.close diff --git a/lib/puma/runner.rb b/lib/puma/runner.rb index 473b4ce59e..013d175d77 100644 --- a/lib/puma/runner.rb +++ b/lib/puma/runner.rb @@ -24,7 +24,7 @@ def wakeup! @wakeup.write "!" unless @wakeup.closed? rescue SystemCallError, IOError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue end def development? diff --git a/lib/puma/server.rb b/lib/puma/server.rb index 004294964f..aac89aecea 100644 --- a/lib/puma/server.rb +++ b/lib/puma/server.rb @@ -146,7 +146,7 @@ def cork_socket(socket) begin skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if skt.kind_of? TCPSocket rescue IOError, SystemCallError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue end end @@ -155,7 +155,7 @@ def uncork_socket(socket) begin skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if skt.kind_of? TCPSocket rescue IOError, SystemCallError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue end end else @@ -176,7 +176,7 @@ def closed_socket?(socket) begin tcp_info = skt.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_INFO) rescue IOError, SystemCallError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue @precheck_closing = false false else @@ -491,7 +491,7 @@ def process_client(client, buffer) begin client.close if close_socket rescue IOError, SystemCallError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue # Already closed rescue StandardError => e @events.unknown_error e, nil, "Client" @@ -583,11 +583,11 @@ def notify_safely(message) @notify << message rescue IOError, NoMethodError, Errno::EPIPE # The server, in another thread, is shutting down - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue rescue RuntimeError => e # Temporary workaround for https://bugs.ruby-lang.org/issues/13239 if e.message.include?('IOError') - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue else raise e end diff --git a/lib/puma/util.rb b/lib/puma/util.rb index d4928e1341..bf1cabc176 100644 --- a/lib/puma/util.rb +++ b/lib/puma/util.rb @@ -10,6 +10,13 @@ def pipe IO.pipe end + # An instance method on Thread has been provided to address https://bugs.ruby-lang.org/issues/13632, + # which currently effects some older versions of Ruby: 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1 + # Additional context: https://github.com/puma/puma/pull/1345 + def purge_interrupt_queue + Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + end + # Unescapes a URI escaped string with +encoding+. +encoding+ will be the # target encoding of the string returned, and it defaults to UTF-8 if defined?(::Encoding) diff --git a/test/test_busy_worker.rb b/test/test_busy_worker.rb index 296c602121..e53213699a 100644 --- a/test/test_busy_worker.rb +++ b/test/test_busy_worker.rb @@ -17,7 +17,7 @@ def teardown def new_connection TCPSocket.new('127.0.0.1', @port).tap {|s| @ios << s} rescue IOError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue retry end diff --git a/test/test_out_of_band_server.rb b/test/test_out_of_band_server.rb index 06f2fa2072..27eec9b7e7 100644 --- a/test/test_out_of_band_server.rb +++ b/test/test_out_of_band_server.rb @@ -21,7 +21,7 @@ def teardown def new_connection TCPSocket.new('127.0.0.1', @port).tap {|s| @ios << s} rescue IOError - Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + Puma::Util.purge_interrupt_queue retry end