mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
temporary workaround for https://bugs.ruby-lang.org/issues/13632 (#1345)
* temporary workaround for https://bugs.ruby-lang.org/issues/13632 Purging interrupt queue if IOError was caught. * fixing only if mri * optimization to avoid redundant checks in empty queue * scoping fix to only affected versions * serving ruby version from mkmf * safe invoking for the workaround * switching to preprocessor vars * purging queue on runtime error * rubocop fix * covering workaround * improving names * styling * rubocop fixes * improved test reporting * wording * condition * improving comment * bugfix moved to separate gem: https://rubygems.org/gems/stopgap_13632 * using stopgap_13632 in gemfile to fix the builds * requiring stopgap for tests
This commit is contained in:
parent
31b02825d3
commit
91416134cb
7 changed files with 26 additions and 4 deletions
4
Gemfile
4
Gemfile
|
@ -14,3 +14,7 @@ gem "minitest", "~> 5.9"
|
||||||
gem "jruby-openssl", :platform => "jruby"
|
gem "jruby-openssl", :platform => "jruby"
|
||||||
|
|
||||||
gem "rubocop", "~> 0.49.1"
|
gem "rubocop", "~> 0.49.1"
|
||||||
|
|
||||||
|
if %w(2.2.7 2.3.4 2.4.1).include? RUBY_VERSION
|
||||||
|
gem "stopgap_13632", "~> 1.0", :platform => "mri"
|
||||||
|
end
|
||||||
|
|
|
@ -111,6 +111,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
@io.close
|
@io.close
|
||||||
rescue IOError
|
rescue IOError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
@wakeup.write "!" unless @wakeup.closed?
|
@wakeup.write "!" unless @wakeup.closed?
|
||||||
rescue SystemCallError, IOError
|
rescue SystemCallError, IOError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -267,6 +268,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
@worker_write << "b#{Process.pid}\n"
|
@worker_write << "b#{Process.pid}\n"
|
||||||
rescue SystemCallError, IOError
|
rescue SystemCallError, IOError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
STDERR.puts "Master seems to have exited, exiting."
|
STDERR.puts "Master seems to have exited, exiting."
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -282,6 +284,7 @@ module Puma
|
||||||
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r} }\n!
|
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r} }\n!
|
||||||
io << payload
|
io << payload
|
||||||
rescue IOError
|
rescue IOError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -118,6 +118,7 @@ module Puma
|
||||||
return if read_and_drop(1) == :timeout
|
return if read_and_drop(1) == :timeout
|
||||||
end
|
end
|
||||||
rescue IOError, SystemCallError
|
rescue IOError, SystemCallError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
# nothing
|
# nothing
|
||||||
ensure
|
ensure
|
||||||
@socket.close
|
@socket.close
|
||||||
|
|
|
@ -28,6 +28,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
ready = IO.select sockets, nil, nil, @sleep_for
|
ready = IO.select sockets, nil, nil, @sleep_for
|
||||||
rescue IOError => e
|
rescue IOError => e
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
if sockets.any? { |socket| socket.closed? }
|
if sockets.any? { |socket| socket.closed? }
|
||||||
STDERR.puts "Error in select: #{e.message} (#{e.class})"
|
STDERR.puts "Error in select: #{e.message} (#{e.class})"
|
||||||
STDERR.puts e.backtrace
|
STDERR.puts e.backtrace
|
||||||
|
@ -195,6 +196,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
@trigger << "c"
|
@trigger << "c"
|
||||||
rescue IOError
|
rescue IOError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -202,6 +204,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
@trigger << "!"
|
@trigger << "!"
|
||||||
rescue IOError
|
rescue IOError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
end
|
end
|
||||||
|
|
||||||
@thread.join
|
@thread.join
|
||||||
|
|
|
@ -110,6 +110,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
socket.setsockopt(6, 3, 1) if socket.kind_of? TCPSocket
|
socket.setsockopt(6, 3, 1) if socket.kind_of? TCPSocket
|
||||||
rescue IOError, SystemCallError
|
rescue IOError, SystemCallError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -117,6 +118,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
socket.setsockopt(6, 3, 0) if socket.kind_of? TCPSocket
|
socket.setsockopt(6, 3, 0) if socket.kind_of? TCPSocket
|
||||||
rescue IOError, SystemCallError
|
rescue IOError, SystemCallError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,6 +129,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO)
|
tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO)
|
||||||
rescue IOError, SystemCallError
|
rescue IOError, SystemCallError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
@precheck_closing = false
|
@precheck_closing = false
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
|
@ -490,6 +493,7 @@ module Puma
|
||||||
begin
|
begin
|
||||||
client.close if close_socket
|
client.close if close_socket
|
||||||
rescue IOError, SystemCallError
|
rescue IOError, SystemCallError
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
# Already closed
|
# Already closed
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
@events.unknown_error self, e, "Client"
|
@events.unknown_error self, e, "Client"
|
||||||
|
@ -897,10 +901,14 @@ module Puma
|
||||||
@notify << message
|
@notify << message
|
||||||
rescue IOError
|
rescue IOError
|
||||||
# The server, in another thread, is shutting down
|
# The server, in another thread, is shutting down
|
||||||
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
rescue RuntimeError => e
|
rescue RuntimeError => e
|
||||||
# The server, in another thread, has been shut down during the system call
|
# Temporary workaround for https://bugs.ruby-lang.org/issues/13239
|
||||||
# https://github.com/puma/puma/pull/1206
|
if e.message.include?('IOError')
|
||||||
raise e unless e.message.include?('IOError')
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
||||||
|
else
|
||||||
|
raise e
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :notify_safely
|
private :notify_safely
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright (c) 2011 Evan Phoenix
|
# Copyright (c) 2011 Evan Phoenix
|
||||||
# Copyright (c) 2005 Zed A. Shaw
|
# Copyright (c) 2005 Zed A. Shaw
|
||||||
|
|
||||||
|
require 'stopgap_13632' if %w(2.2.7 2.3.4 2.4.1).include? RUBY_VERSION
|
||||||
|
|
||||||
begin
|
begin
|
||||||
require "bundler/setup"
|
require "bundler/setup"
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
|
|
Loading…
Reference in a new issue