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

Use separate activated_sockets hash in Binder for socket activation

* Keep only the basic known info from imported FD/Socket as keys

  * Then with creating listeners in Binders.parse look for available
    Sockets using only these details.

This allows socket activation to work with ssl and other listeners
where additional parameters are specified in config. These parameters
could not otherwise be determined from an imported FD which previously
caused lookup/matching to fail, followed by failed startup due to
ports being "already in use" (by the same socket activation).
This commit is contained in:
David Kellum 2016-04-01 12:45:48 -07:00
parent 13a5dac22b
commit 3030870afa

View file

@ -11,6 +11,7 @@ module Puma
@events = events
@listeners = []
@inherited_fds = {}
@activated_sockets = {}
@unix_paths = []
@proto_env = {
@ -60,16 +61,16 @@ module Puma
fd = num + 3
sock = TCPServer.for_fd(fd)
begin
url = "unix://" + Socket.unpack_sockaddr_un(sock.getsockname)
key = [ :unix, Socket.unpack_sockaddr_un(sock.getsockname) ]
rescue ArgumentError
port, addr = Socket.unpack_sockaddr_in(sock.getsockname)
if addr =~ /\:/
addr = "[#{addr}]"
end
url = "tcp://#{addr}:#{port}"
key = [ :tcp, addr, port ]
end
@inherited_fds[url] = sock
@events.debug "Registered #{url} for inheriting from LISTEN_FDS"
@activated_sockets[key] = sock
@events.debug "Registered #{key.join ':'} for activation from LISTEN_FDS"
end
remove << k << 'LISTEN_PID'
end
@ -88,6 +89,9 @@ module Puma
if fd = @inherited_fds.delete(str)
logger.log "* Inherited #{str}"
io = inherit_tcp_listener uri.host, uri.port, fd
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
logger.log "* Activated #{str}"
io = inherit_tcp_listener uri.host, uri.port, sock
else
params = Util.parse_query uri.query
@ -105,6 +109,9 @@ module Puma
if fd = @inherited_fds.delete(str)
logger.log "* Inherited #{str}"
io = inherit_unix_listener path, fd
elsif sock = @activated_sockets.delete([ :unix, path ])
logger.log "* Activated #{str}"
io = inherit_unix_listener path, sock
else
logger.log "* Listening on #{str}"
@ -191,6 +198,9 @@ module Puma
if fd = @inherited_fds.delete(str)
logger.log "* Inherited #{str}"
io = inherit_ssl_listener fd, ctx
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
logger.log "* Activated #{str}"
io = inherit_ssl_listener sock, ctx
else
logger.log "* Listening on #{str}"
io = add_ssl_listener uri.host, uri.port, ctx
@ -208,12 +218,7 @@ module Puma
logger.log "* Closing unused inherited connection: #{str}"
begin
if fd.kind_of? TCPServer
fd.close
else
IO.for_fd(fd).close
end
IO.for_fd(fd).close
rescue SystemCallError
end
@ -225,6 +230,17 @@ module Puma
end
end
# Also close any unsued activated sockets
@activated_sockets.each do |key, sock|
logger.log "* Closing unused activated socket: #{key.join ':'}"
begin
sock.close
rescue SystemCallError
end
# We have to unlink a unix socket path that's not being used
File.unlink key[1] if key[0] == :unix
end
end
# Tell the server to listen on host +host+, port +port+.