1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

More elaborate exception handling. (#2700)

* More elaborate exception handling. Fixes #2699.

* Add TestIntegrationSingle#test_closed_listener

Co-authored-by: MSP-Greg <Greg.mpls@gmail.com>
This commit is contained in:
Samuel Williams 2021-09-17 04:54:14 +12:00 committed by GitHub
parent 319f84db13
commit cb080346a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 3 deletions

View file

@ -356,7 +356,10 @@ module Puma
pool << client
end
end
rescue Object => e
rescue IOError, Errno::EBADF
# In the case that any of the sockets are unexpectedly close.
raise
rescue StandardError => e
@events.unknown_error e, nil, "Listen loop"
end
end

View file

@ -50,7 +50,7 @@ class TestIntegration < Minitest::Test
assert(system(*args, out: File::NULL, err: File::NULL))
end
def cli_server(argv, unix: false, config: nil)
def cli_server(argv, unix: false, config: nil, merge_err: false)
if config
config_file = Tempfile.new(%w(config .rb))
config_file.write config
@ -64,7 +64,11 @@ class TestIntegration < Minitest::Test
@tcp_port = UniquePort.call
cmd = "#{BASE} #{puma_path} #{config} -b tcp://#{HOST}:#{@tcp_port} #{argv}"
end
@server = IO.popen(cmd, "r")
if merge_err
@server = IO.popen(cmd, "r", :err=>[:child, :out])
else
@server = IO.popen(cmd, "r")
end
wait_for_server_to_boot
@pid = @server.pid
@server

View file

@ -0,0 +1,6 @@
require 'objspace'
run lambda { |env|
ios = ObjectSpace.each_object(::TCPServer).to_a.tap { |a| a.each(&:close) }
[200, [], ["#{ios.inspect}\n"]]
}

View file

@ -178,4 +178,29 @@ class TestIntegrationSingle < TestIntegration
@server.close unless @server.closed?
@server = nil
end
# listener is closed 'externally' while Puma is in the IO.select statement
def test_closed_listener
skip_unless_signal_exist? :TERM
cli_server "test/rackup/close_listeners.ru", merge_err: true
read_body connect
begin
Timeout.timeout(5) do
begin
Process.kill :SIGTERM, @pid
rescue Errno::ESRCH
end
begin
Process.wait2 @pid
rescue Errno::ECHILD
end
end
rescue Timeout::Error
Process.kill :SIGKILL, @pid
assert false, "Process froze"
end
assert true
end
end