From 2178202d8f86301c34edcbf5f77e5af7731f0aca Mon Sep 17 00:00:00 2001 From: "Joshua T. Mckinney" Date: Sun, 15 May 2016 22:11:26 -0500 Subject: [PATCH] detect forks --- HISTORY.md | 3 ++- README.md | 29 +---------------------------- lib/hot_tub/pool.rb | 41 +++++++++++------------------------------ 3 files changed, 14 insertions(+), 59 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index aafeb4a..c17c847 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,11 +5,12 @@ Head ======= - None yet. -1.0.1 +1.1.0 ======= - Close orphan clients outside of synchonize - Freeze alarm message - Detect dead resources and reap +- Detect fork 1.0.0 ======= diff --git a/README.md b/README.md index bbc1091..641ec1c 100644 --- a/README.md +++ b/README.md @@ -140,35 +140,8 @@ a lambda that accepts the client as an argument or symbol representing a method ## Forking -HotTub's `#reset!` methods close all idle connections, prevents connections in use from returning -to the pool and attempts to close orphaned connections as they attempt to return. +HotTub::Pool automatically detects forks and drains the pool, so no additional "after fork" code is required. - # Puma - on_worker_boot do - - # If you let HotTub manage all your connections - HotTub.reset! - - # If you have your own HotTub::Sessions - MY_SESSIONS.reset! - - # If you have any one-off pools - MY_POOL.reset! - - end - - # Unicorn - before_fork do |server, worker| - - # If you let HotTub manage all your connections - HotTub.reset! - - # If you have your own HotTub::Sessions - MY_SESSIONS.reset! - - # If you have any one-off pools - MY_POOL.reset! - end ## Contributing to HotTub diff --git a/lib/hot_tub/pool.rb b/lib/hot_tub/pool.rb index 2d9db25..6bc21e4 100644 --- a/lib/hot_tub/pool.rb +++ b/lib/hot_tub/pool.rb @@ -116,12 +116,15 @@ def initialize(opts={},&client_block) @never_block = (@max_size == 0) + @pid = Process.pid + at_exit {shutdown!} unless @sessions_key end # Preform an operations with a client/connection. # Requires a block that receives the client. def run + drain! if forked? clnt = pop yield clnt ensure @@ -158,48 +161,22 @@ def drain! ensure @_out.clear @_pool.clear + @pid = Process.pid @cond.broadcast end end nil end alias :close! :drain! - - # Reset the pool. - # or if shutdown allow threads to quickly finish their work - # Clients from the previous pool will not return to pool. - def reset! - HotTub.logger.info "[HotTub] Resetting pool #{@name}!" if HotTub.logger - @mutex.synchronize do - begin - while clnt = @_pool.pop - close_client(clnt) - end - ensure - @_out.clear - @_pool.clear - @cond.broadcast - end - end - nil - end + alias :reset! :drain! # Kills the reaper and drains the pool. def shutdown! HotTub.logger.info "[HotTub] Shutting down pool #{@name}!" if HotTub.logger @shutdown = true kill_reaper if @reaper - @mutex.synchronize do - begin - while clnt = @_pool.pop - close_client(clnt) - end - ensure - @_out.clear - @_pool.clear - @cond.broadcast - end - end + drain! + @shutdown = false nil end @@ -250,6 +227,10 @@ def max_size=max_size @max_size = max_size end + def forked? + @pid != Process.pid + end + private ALARM_MESSAGE = "Could not fetch a free client in time. Consider increasing your pool size.".freeze