mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Close kept alive sockets on restart. Fixes #144
This commit is contained in:
parent
074adfbf4d
commit
810144e77f
5 changed files with 72 additions and 2 deletions
|
@ -325,12 +325,13 @@ module Puma
|
|||
|
||||
@listeners << [str, io]
|
||||
when "unix"
|
||||
path = "#{uri.host}#{uri.path}"
|
||||
|
||||
if fd = @inherited_fds.delete(str)
|
||||
log "* Inherited #{str}"
|
||||
io = server.inherit_unix_listener uri.path, fd
|
||||
io = server.inherit_unix_listener path, fd
|
||||
else
|
||||
log "* Listening on #{str}"
|
||||
path = "#{uri.host}#{uri.path}"
|
||||
|
||||
umask = nil
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@ module Puma
|
|||
def initialize(stdout, stderr)
|
||||
@stdout = stdout
|
||||
@stderr = stderr
|
||||
|
||||
@stdout.sync = true
|
||||
@stderr.sync = true
|
||||
end
|
||||
|
||||
attr_reader :stdout, :stderr
|
||||
|
|
|
@ -30,6 +30,15 @@ module Puma
|
|||
when "*"
|
||||
sockets += @input
|
||||
@input.clear
|
||||
when "c"
|
||||
sockets.delete_if do |s|
|
||||
if s == @ready
|
||||
false
|
||||
else
|
||||
s.close
|
||||
true
|
||||
end
|
||||
end
|
||||
when "!"
|
||||
return
|
||||
end
|
||||
|
@ -121,8 +130,14 @@ module Puma
|
|||
end
|
||||
end
|
||||
|
||||
# Close all watched sockets and clear them from being watched
|
||||
def clear!
|
||||
@trigger << "c"
|
||||
end
|
||||
|
||||
def shutdown
|
||||
@trigger << "!"
|
||||
@thread.join
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -261,6 +261,8 @@ module Puma
|
|||
end
|
||||
end
|
||||
|
||||
@reactor.clear! if @status == :restart
|
||||
|
||||
@reactor.shutdown
|
||||
graceful_shutdown if @status == :stop
|
||||
ensure
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
require "rbconfig"
|
||||
require 'test/unit'
|
||||
require 'socket'
|
||||
require 'timeout'
|
||||
|
||||
require 'puma/cli'
|
||||
require 'puma/control_cli'
|
||||
|
@ -10,12 +11,35 @@ class TestIntegration < Test::Unit::TestCase
|
|||
@state_path = "test/test_puma.state"
|
||||
@bind_path = "test/test_server.sock"
|
||||
@control_path = "test/test_control.sock"
|
||||
@tcp_port = 9998
|
||||
|
||||
@server = nil
|
||||
end
|
||||
|
||||
def teardown
|
||||
File.unlink @state_path rescue nil
|
||||
File.unlink @bind_path rescue nil
|
||||
File.unlink @control_path rescue nil
|
||||
|
||||
if @server
|
||||
Process.kill "INT", @server.pid
|
||||
Process.wait @server.pid
|
||||
@server.close
|
||||
end
|
||||
end
|
||||
|
||||
def server(opts)
|
||||
core = "#{Gem.ruby} -rubygems -Ilib bin/puma"
|
||||
cmd = "#{core} --restart-cmd '#{core}' -b tcp://127.0.0.1:#{@tcp_port} #{opts}"
|
||||
@server = IO.popen(cmd, "r")
|
||||
|
||||
true until @server.gets =~ /Ctrl-C/
|
||||
|
||||
@server
|
||||
end
|
||||
|
||||
def signal(which)
|
||||
Process.kill which, @server.pid
|
||||
end
|
||||
|
||||
def test_stop_via_pumactl
|
||||
|
@ -45,4 +69,29 @@ class TestIntegration < Test::Unit::TestCase
|
|||
|
||||
assert_kind_of Thread, t.join(1), "server didn't stop"
|
||||
end
|
||||
|
||||
def test_restart_closes_keepalive_sockets
|
||||
server("-q test/hello.ru")
|
||||
|
||||
s = TCPSocket.new "localhost", @tcp_port
|
||||
s << "GET / HTTP/1.1\r\n\r\n"
|
||||
true until s.gets == "\r\n"
|
||||
|
||||
s.readpartial(20)
|
||||
signal :USR2
|
||||
|
||||
true until @server.gets =~ /Ctrl-C/
|
||||
|
||||
s.write "GET / HTTP/1.1\r\n\r\n"
|
||||
|
||||
assert_raises Errno::ECONNRESET do
|
||||
Timeout.timeout(2) do
|
||||
s.read(2)
|
||||
end
|
||||
end
|
||||
|
||||
s = TCPSocket.new "localhost", @tcp_port
|
||||
s << "GET / HTTP/1.0\r\n\r\n"
|
||||
assert_equal "Hello World", s.read.split("\r\n").last
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue