about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2013-10-30 18:32:53 +0000
committerEric Wong <normalperson@yhbt.net>2013-10-31 05:04:30 +0000
commit3741b945dcaf2e432f9e0088b4553d17f5c68f2b (patch)
tree716e849598eb744e488b1de68309b92c817a0703 /lib
parentbfe699496ced8f73f659da0f0857fda614fb40b6 (diff)
downloadyahns-3741b945dcaf2e432f9e0088b4553d17f5c68f2b.tar.gz
Otherwise, the server may stay running forever if a client chooses
to stay forever (and there is no FD pressure).
Diffstat (limited to 'lib')
-rw-r--r--lib/yahns/config.rb7
-rw-r--r--lib/yahns/fdmap.rb1
-rw-r--r--lib/yahns/server.rb15
-rw-r--r--lib/yahns/server_mp.rb2
4 files changed, 22 insertions, 3 deletions
diff --git a/lib/yahns/config.rb b/lib/yahns/config.rb
index c4c1b41..e48ba4e 100644
--- a/lib/yahns/config.rb
+++ b/lib/yahns/config.rb
@@ -73,6 +73,11 @@ class Yahns::Config # :nodoc:
     end
   end
 
+  def shutdown_timeout(sec)
+    var = _check_in_block(nil, :shutdown_timeout)
+    @set[var] = _check_int(var, sec, 0)
+  end
+
   def worker_processes(nr, &blk)
     var =_check_in_block(nil, :worker_processes)
     @set[var] = _check_int(var, nr, 1)
@@ -392,7 +397,7 @@ class Yahns::Config # :nodoc:
       io.sync = true
     end
 
-    [ :logger, :pid, :worker_processes, :user,
+    [ :logger, :pid, :worker_processes, :user, :shutdown_timeout,
       :worker_atfork_prepare, :worker_atfork_parent, :worker_atfork_child
     ].each do |var|
       val = @set[var]
diff --git a/lib/yahns/fdmap.rb b/lib/yahns/fdmap.rb
index 8dda4e6..97e9f44 100644
--- a/lib/yahns/fdmap.rb
+++ b/lib/yahns/fdmap.rb
@@ -56,6 +56,7 @@ class Yahns::Fdmap # :nodoc:
   end
 
   # this is only called in Errno::EMFILE/Errno::ENFILE situations
+  # and graceful shutdown
   def desperate_expire_for(io, timeout)
     @fdmap_mtx.synchronize { __expire_for(io, timeout) }
   end
diff --git a/lib/yahns/server.rb b/lib/yahns/server.rb
index 4bd523f..6439918 100644
--- a/lib/yahns/server.rb
+++ b/lib/yahns/server.rb
@@ -12,12 +12,14 @@ class Yahns::Server # :nodoc:
   attr_accessor :logger
   attr_writer :user
   attr_writer :worker_processes
+  attr_writer :shutdown_timeout
   attr_writer :worker_atfork_prepare
   attr_writer :worker_atfork_parent
   attr_writer :worker_atfork_child
   include Yahns::SocketHelper
 
   def initialize(config)
+    @shutdown_timeout = nil
     @reexec_pid = 0
     @daemon_pipe = nil # writable IO or true
     @config = config
@@ -339,6 +341,8 @@ class Yahns::Server # :nodoc:
     # spin up applications (which are preload: false)
     @config.app_ctx.each(&:after_fork_init)
 
+    @shutdown_timeout ||= @config.app_ctx.map(&:client_timeout).max
+
     # spin up acceptor threads, clients flow into worker queues after this
     @listeners.each do |l|
       opts = sock_opts(l)
@@ -413,6 +417,15 @@ class Yahns::Server # :nodoc:
     alive
   end
 
+  def dropping(fdmap)
+    if drop_acceptors[0] || fdmap.size > 0
+      fdmap.desperate_expire_for(nil, @shutdown_timeout)
+      true
+    else
+      false
+    end
+  end
+
   # single-threaded only, this is overriden if @worker_processes is non-nil
   def join
     daemon_ready
@@ -422,7 +435,7 @@ class Yahns::Server # :nodoc:
       alive = sp_sig_handle(alive)
     rescue => e
       Yahns::Log.exception(@logger, "main loop", e)
-    end while alive || drop_acceptors[0] || fdmap.size > 0
+    end while alive || dropping(fdmap)
     unlink_pid_safe(@pid) if @pid
   ensure
     quit_finish
diff --git a/lib/yahns/server_mp.rb b/lib/yahns/server_mp.rb
index 551cf69..4957c22 100644
--- a/lib/yahns/server_mp.rb
+++ b/lib/yahns/server_mp.rb
@@ -142,7 +142,7 @@ module Yahns::ServerMP # :nodoc:
       alive = mp_sig_handle(worker, alive)
     rescue => e
       Yahns::Log.exception(@logger, "main worker loop", e)
-    end while alive || drop_acceptors[0] || fdmap.size > 0
+    end while alive || dropping(fdmap)
     exit
   ensure
     quit_finish