diff options
author | Eric Wong <e@80x24.org> | 2013-11-01 00:04:59 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-11-01 00:04:59 +0000 |
commit | 7c32323bdd375b1167b42991c081e3b579ad8243 (patch) | |
tree | d044e1a6810437d331e2f3d54c974ca45400877b | |
parent | 885b2f28f3b31539140a8466e6205903bc7cf1d2 (diff) | |
download | yahns-7c32323bdd375b1167b42991c081e3b579ad8243.tar.gz |
It's conceivable a sub-optimally configured instance can have too many Unix sockets connected to us. This also implements expiry for systems without sufficient "struct tcp_info" support.
-rw-r--r-- | lib/yahns.rb | 1 | ||||
-rw-r--r-- | lib/yahns/acceptor.rb | 7 | ||||
-rw-r--r-- | lib/yahns/client_expire_generic.rb (renamed from lib/yahns/client_expire_portable.rb) | 17 | ||||
-rw-r--r-- | lib/yahns/client_expire_tcpi.rb (renamed from lib/yahns/client_expire.rb) | 11 | ||||
-rw-r--r-- | lib/yahns/http_client.rb | 1 | ||||
-rw-r--r-- | lib/yahns/server.rb | 10 |
6 files changed, 34 insertions, 13 deletions
diff --git a/lib/yahns.rb b/lib/yahns.rb index b493dc2..39747a8 100644 --- a/lib/yahns.rb +++ b/lib/yahns.rb @@ -61,7 +61,6 @@ require_relative 'yahns/queue_epoll' require_relative 'yahns/stream_input' require_relative 'yahns/tee_input' require_relative 'yahns/queue_egg' -require_relative 'yahns/client_expire' require_relative 'yahns/http_response' require_relative 'yahns/http_client' require_relative 'yahns/http_context' diff --git a/lib/yahns/acceptor.rb b/lib/yahns/acceptor.rb index 2a212cf..c61975a 100644 --- a/lib/yahns/acceptor.rb +++ b/lib/yahns/acceptor.rb @@ -1,6 +1,8 @@ # -*- encoding: binary -*- # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> et. al. # License: GPLv3 or later (see COPYING for details) +require_relative 'client_expire_tcpi' +require_relative 'client_expire_generic' module Yahns::Acceptor # :nodoc: def __ac_quit_done? @thrs.delete_if do |t| @@ -62,4 +64,9 @@ module Yahns::Acceptor # :nodoc: end end end + + def expire_mod + (Yahns::TCPServer === self && Yahns.const_defined?(:ClientExpireTCPI)) ? + Yahns::ClientExpireTCPI : Yahns::ClientExpireGeneric + end end diff --git a/lib/yahns/client_expire_portable.rb b/lib/yahns/client_expire_generic.rb index daf396c..f2f5369 100644 --- a/lib/yahns/client_expire_portable.rb +++ b/lib/yahns/client_expire_generic.rb @@ -1,19 +1,25 @@ # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) -module Yahns::ClientExpire # :nodoc: +module Yahns::ClientExpireGeneric # :nodoc: def __timestamp Time.now.to_f end + def yahns_init + super # Yahns::HttpClient#yahns_init + @last_io_at = 0 + end + def yahns_expire(timeout) - return 0 if closed? # still racy, but avoid the exception in most cases + return 0 if closed? if (__timestamp - @last_io_at) > timeout shutdown 1 else 0 end - rescue # the IO#closed? check is racy + # shutdown may race with the shutdown in http_response_done + rescue 0 end @@ -31,4 +37,9 @@ module Yahns::ClientExpire # :nodoc: @last_io_at = __timestamp super end + + def trysendfile(*args) + @last_io_at = __timestamp + super + end end diff --git a/lib/yahns/client_expire.rb b/lib/yahns/client_expire_tcpi.rb index 0a21c7b..8a89a42 100644 --- a/lib/yahns/client_expire.rb +++ b/lib/yahns/client_expire_tcpi.rb @@ -1,5 +1,6 @@ # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +require 'raindrops' # included in Yahns::HttpClient # @@ -7,7 +8,7 @@ # on idle clients # # we absolutely DO NOT issue IO#close in here, only BasicSocket#shutdown -module Yahns::ClientExpire # :nodoc: +module Yahns::ClientExpireTCPI # :nodoc: def yahns_expire(timeout) # rarely called return 0 if closed? @@ -31,10 +32,10 @@ module Yahns::ClientExpire # :nodoc: else 0 end - # we also do not expire UNIX domain sockets - # (since those are the most trusted of local clients) - # the IO#closed? check is racy + # shutdown may race with the shutdown in http_response_done rescue 0 end -end +# FreeBSD has "struct tcp_info", too, but does not support all the fields +# Linux does as of FreeBSD 9 (haven't checked FreeBSD 10, yet). +end if RUBY_PLATFORM =~ /linux/ diff --git a/lib/yahns/http_client.rb b/lib/yahns/http_client.rb index 721be04..5f137fd 100644 --- a/lib/yahns/http_client.rb +++ b/lib/yahns/http_client.rb @@ -8,7 +8,6 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc: Unicorn::HttpParser.keepalive_requests = 0xffffffff include Yahns::HttpResponse - include Yahns::ClientExpire QEV_FLAGS = Yahns::Queue::QEV_RD # used by acceptor # A frozen format for this is about 15% faster (note from Mongrel) diff --git a/lib/yahns/server.rb b/lib/yahns/server.rb index 330bcc8..4adf0c9 100644 --- a/lib/yahns/server.rb +++ b/lib/yahns/server.rb @@ -359,9 +359,12 @@ class Yahns::Server # :nodoc: @listeners.each do |l| opts = sock_opts(l) ctx = opts[:yahns_app_ctx] + ctx_list = opts[:yahns_app_ctx_list] ||= [] qegg = ctx.qegg || @config.qeggs[:default] ctx.queue = queues[qegg] ||= qegg_vivify(qegg, fdmap) - + ctx = ctx.dup + ctx.__send__(:include, l.expire_mod) + ctx_list << ctx # acceptors feed the the queues l.spawn_acceptor(opts[:threads] || 1, @logger, ctx) end @@ -379,8 +382,9 @@ class Yahns::Server # :nodoc: drop_acceptors # stop acceptors, we close epolls in quit_done exit(0) unless alive # drop connections immediately if signaled twice @config.config_listeners.each_value do |opts| - ctx = opts[:yahns_app_ctx] or next - ctx.persistent_connections = false # Yahns::HttpContext + list= opts[:yahns_app_ctx_list] or next + # Yahns::HttpContext#persistent_connections= + list.each { |ctx| ctx.persistent_connections = false } end false end |