1
0
Fork 0
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:
Evan Phoenix 2012-09-02 23:33:09 -04:00
parent 074adfbf4d
commit 810144e77f
5 changed files with 72 additions and 2 deletions

View file

@ -325,12 +325,13 @@ module Puma
@listeners << [str, io] @listeners << [str, io]
when "unix" when "unix"
path = "#{uri.host}#{uri.path}"
if fd = @inherited_fds.delete(str) if fd = @inherited_fds.delete(str)
log "* Inherited #{str}" log "* Inherited #{str}"
io = server.inherit_unix_listener uri.path, fd io = server.inherit_unix_listener path, fd
else else
log "* Listening on #{str}" log "* Listening on #{str}"
path = "#{uri.host}#{uri.path}"
umask = nil umask = nil

View file

@ -16,6 +16,9 @@ module Puma
def initialize(stdout, stderr) def initialize(stdout, stderr)
@stdout = stdout @stdout = stdout
@stderr = stderr @stderr = stderr
@stdout.sync = true
@stderr.sync = true
end end
attr_reader :stdout, :stderr attr_reader :stdout, :stderr

View file

@ -30,6 +30,15 @@ module Puma
when "*" when "*"
sockets += @input sockets += @input
@input.clear @input.clear
when "c"
sockets.delete_if do |s|
if s == @ready
false
else
s.close
true
end
end
when "!" when "!"
return return
end end
@ -121,8 +130,14 @@ module Puma
end end
end end
# Close all watched sockets and clear them from being watched
def clear!
@trigger << "c"
end
def shutdown def shutdown
@trigger << "!" @trigger << "!"
@thread.join
end end
end end
end end

View file

@ -261,6 +261,8 @@ module Puma
end end
end end
@reactor.clear! if @status == :restart
@reactor.shutdown @reactor.shutdown
graceful_shutdown if @status == :stop graceful_shutdown if @status == :stop
ensure ensure

View file

@ -1,6 +1,7 @@
require "rbconfig" require "rbconfig"
require 'test/unit' require 'test/unit'
require 'socket' require 'socket'
require 'timeout'
require 'puma/cli' require 'puma/cli'
require 'puma/control_cli' require 'puma/control_cli'
@ -10,12 +11,35 @@ class TestIntegration < Test::Unit::TestCase
@state_path = "test/test_puma.state" @state_path = "test/test_puma.state"
@bind_path = "test/test_server.sock" @bind_path = "test/test_server.sock"
@control_path = "test/test_control.sock" @control_path = "test/test_control.sock"
@tcp_port = 9998
@server = nil
end end
def teardown def teardown
File.unlink @state_path rescue nil File.unlink @state_path rescue nil
File.unlink @bind_path rescue nil File.unlink @bind_path rescue nil
File.unlink @control_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 end
def test_stop_via_pumactl 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" assert_kind_of Thread, t.join(1), "server didn't stop"
end 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 end