From a764983fccd6cce64043d76e09a5e1718e7f8fd6 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 17 Oct 2009 22:42:56 -0700 Subject: refactor graceful shutdowns again, harder We use the "G" global constant from the Rev model everywhere to simplify things a little. Test cases are more consistent now, too. --- lib/rainbows/rev.rb | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'lib/rainbows/rev.rb') diff --git a/lib/rainbows/rev.rb b/lib/rainbows/rev.rb index 7e5ca27..7d941f6 100644 --- a/lib/rainbows/rev.rb +++ b/lib/rainbows/rev.rb @@ -33,19 +33,15 @@ module Rainbows module Rev - # global vars because class/instance variables are confusing me :< - # this struct is only accessed inside workers and thus private to each - G = Struct.new(:nr, :max, :logger, :alive, :app).new - include Base class Client < ::Rev::IO include Unicorn include Rainbows::Const - G = Rainbows::Rev::G + G = Rainbows::G def initialize(io) - G.nr += 1 + G.cur += 1 super(io) @remote_addr = ::TCPSocket === io ? io.peeraddr.last : LOCALHOST @env = {} @@ -91,7 +87,7 @@ module Rainbows end def on_close - G.nr -= 1 + G.cur -= 1 end def tmpio @@ -143,10 +139,10 @@ module Rainbows end class Server < ::Rev::IO - G = Rainbows::Rev::G + G = Rainbows::G def on_readable - return if G.nr >= G.max + return if G.cur >= G.max begin Client.new(@_io.accept_nonblock).attach(::Rev::Loop.default) rescue Errno::EAGAIN, Errno::ECONNBORTED @@ -160,13 +156,21 @@ module Rainbows # given a INT, QUIT, or TERM signal) def worker_loop(worker) init_worker_process(worker) - G.nr = 0 - G.max = worker_connections - G.alive = true - G.logger = logger - G.app = app + graceful_waiter = nil + trap(:QUIT) do + G.alive = false + LISTENERS.map! { |s| s.close rescue nil } + # Rev may get stuck in a loop with no events possible, spawn a new + # thread to join on graceful exits when our client count goes to zero + graceful_waiter = Thread.new { + sleep(0.1) while G.cur > 0 + exit + } + end + LISTENERS.map! { |s| Server.new(s).attach(::Rev::Loop.default) } ::Rev::Loop.default.run + graceful_waiter.join(timeout * 2.0) end end -- cgit v1.2.3-24-ge0c7