mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
[ruby/rubygems] Update vendored version of connection_pool to 2.5.4
https://github.com/ruby/rubygems/commit/3f5330c9fc
This commit is contained in:
parent
e68c0fc75b
commit
917fd39982
@ -39,7 +39,7 @@ end
|
||||
# - :auto_reload_after_fork - automatically drop all connections after fork, defaults to true
|
||||
#
|
||||
class Bundler::ConnectionPool
|
||||
DEFAULTS = {size: 5, timeout: 5, auto_reload_after_fork: true}
|
||||
DEFAULTS = {size: 5, timeout: 5, auto_reload_after_fork: true}.freeze
|
||||
|
||||
def self.wrap(options, &block)
|
||||
Wrapper.new(options, &block)
|
||||
@ -99,7 +99,8 @@ class Bundler::ConnectionPool
|
||||
@available = TimedStack.new(@size, &block)
|
||||
@key = :"pool-#{@available.object_id}"
|
||||
@key_count = :"pool-#{@available.object_id}-count"
|
||||
INSTANCES[self] = self if INSTANCES
|
||||
@discard_key = :"pool-#{@available.object_id}-discard"
|
||||
INSTANCES[self] = self if @auto_reload_after_fork && INSTANCES
|
||||
end
|
||||
|
||||
def with(options = {})
|
||||
@ -116,20 +117,65 @@ class Bundler::ConnectionPool
|
||||
end
|
||||
alias_method :then, :with
|
||||
|
||||
##
|
||||
# Marks the current thread's checked-out connection for discard.
|
||||
#
|
||||
# When a connection is marked for discard, it will not be returned to the pool
|
||||
# when checked in. Instead, the connection will be discarded.
|
||||
# This is useful when a connection has become invalid or corrupted
|
||||
# and should not be reused.
|
||||
#
|
||||
# Takes an optional block that will be called with the connection to be discarded.
|
||||
# The block should perform any necessary clean-up on the connection.
|
||||
#
|
||||
# @yield [conn]
|
||||
# @yieldparam conn [Object] The connection to be discarded.
|
||||
# @yieldreturn [void]
|
||||
#
|
||||
#
|
||||
# Note: This only affects the connection currently checked out by the calling thread.
|
||||
# The connection will be discarded when +checkin+ is called.
|
||||
#
|
||||
# @return [void]
|
||||
#
|
||||
# @example
|
||||
# pool.with do |conn|
|
||||
# begin
|
||||
# conn.execute("SELECT 1")
|
||||
# rescue SomeConnectionError
|
||||
# pool.discard_current_connection # Mark connection as bad
|
||||
# raise
|
||||
# end
|
||||
# end
|
||||
def discard_current_connection(&block)
|
||||
::Thread.current[@discard_key] = block || proc { |conn| conn }
|
||||
end
|
||||
|
||||
def checkout(options = {})
|
||||
if ::Thread.current[@key]
|
||||
::Thread.current[@key_count] += 1
|
||||
::Thread.current[@key]
|
||||
else
|
||||
::Thread.current[@key_count] = 1
|
||||
::Thread.current[@key] = @available.pop(options[:timeout] || @timeout)
|
||||
::Thread.current[@key] = @available.pop(options[:timeout] || @timeout, options)
|
||||
end
|
||||
end
|
||||
|
||||
def checkin(force: false)
|
||||
if ::Thread.current[@key]
|
||||
if ::Thread.current[@key_count] == 1 || force
|
||||
@available.push(::Thread.current[@key])
|
||||
if ::Thread.current[@discard_key]
|
||||
begin
|
||||
@available.decrement_created
|
||||
::Thread.current[@discard_key].call(::Thread.current[@key])
|
||||
rescue
|
||||
nil
|
||||
ensure
|
||||
::Thread.current[@discard_key] = nil
|
||||
end
|
||||
else
|
||||
@available.push(::Thread.current[@key])
|
||||
end
|
||||
::Thread.current[@key] = nil
|
||||
::Thread.current[@key_count] = nil
|
||||
else
|
||||
@ -146,7 +192,6 @@ class Bundler::ConnectionPool
|
||||
# Shuts down the Bundler::ConnectionPool by passing each connection to +block+ and
|
||||
# then removing it from the pool. Attempting to checkout a connection after
|
||||
# shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+.
|
||||
|
||||
def shutdown(&block)
|
||||
@available.shutdown(&block)
|
||||
end
|
||||
@ -155,7 +200,6 @@ class Bundler::ConnectionPool
|
||||
# Reloads the Bundler::ConnectionPool by passing each connection to +block+ and then
|
||||
# removing it the pool. Subsequent checkouts will create new connections as
|
||||
# needed.
|
||||
|
||||
def reload(&block)
|
||||
@available.shutdown(reload: true, &block)
|
||||
end
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
##
|
||||
# The TimedStack manages a pool of homogeneous connections (or any resource
|
||||
# you wish to manage). Connections are created lazily up to a given maximum
|
||||
# you wish to manage). Connections are created lazily up to a given maximum
|
||||
# number.
|
||||
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# ts = TimedStack.new(1) { MyConnection.new }
|
||||
@ -16,14 +16,12 @@
|
||||
# conn = ts.pop
|
||||
# ts.pop timeout: 5
|
||||
# #=> raises Bundler::ConnectionPool::TimeoutError after 5 seconds
|
||||
|
||||
class Bundler::ConnectionPool::TimedStack
|
||||
attr_reader :max
|
||||
|
||||
##
|
||||
# Creates a new pool with +size+ connections that are created from the given
|
||||
# +block+.
|
||||
|
||||
def initialize(size = 0, &block)
|
||||
@create_block = block
|
||||
@created = 0
|
||||
@ -35,9 +33,8 @@ class Bundler::ConnectionPool::TimedStack
|
||||
end
|
||||
|
||||
##
|
||||
# Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be
|
||||
# Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be
|
||||
# used by subclasses that extend TimedStack.
|
||||
|
||||
def push(obj, options = {})
|
||||
@mutex.synchronize do
|
||||
if @shutdown_block
|
||||
@ -53,14 +50,13 @@ class Bundler::ConnectionPool::TimedStack
|
||||
alias_method :<<, :push
|
||||
|
||||
##
|
||||
# Retrieves a connection from the stack. If a connection is available it is
|
||||
# immediately returned. If no connection is available within the given
|
||||
# Retrieves a connection from the stack. If a connection is available it is
|
||||
# immediately returned. If no connection is available within the given
|
||||
# timeout a Bundler::ConnectionPool::TimeoutError is raised.
|
||||
#
|
||||
# +:timeout+ is the only checked entry in +options+ and is preferred over
|
||||
# the +timeout+ argument (which will be removed in a future release). Other
|
||||
# the +timeout+ argument (which will be removed in a future release). Other
|
||||
# options may be used by subclasses that extend TimedStack.
|
||||
|
||||
def pop(timeout = 0.5, options = {})
|
||||
options, timeout = timeout, 0.5 if Hash === timeout
|
||||
timeout = options.fetch :timeout, timeout
|
||||
@ -69,7 +65,9 @@ class Bundler::ConnectionPool::TimedStack
|
||||
@mutex.synchronize do
|
||||
loop do
|
||||
raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
|
||||
return fetch_connection(options) if connection_stored?(options)
|
||||
if (conn = try_fetch_connection(options))
|
||||
return conn
|
||||
end
|
||||
|
||||
connection = try_create(options)
|
||||
return connection if connection
|
||||
@ -86,7 +84,6 @@ class Bundler::ConnectionPool::TimedStack
|
||||
# removing it from the pool. Attempting to checkout a connection after
|
||||
# shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+ unless
|
||||
# +:reload+ is +true+.
|
||||
|
||||
def shutdown(reload: false, &block)
|
||||
raise ArgumentError, "shutdown must receive a block" unless block
|
||||
|
||||
@ -121,14 +118,12 @@ class Bundler::ConnectionPool::TimedStack
|
||||
|
||||
##
|
||||
# Returns +true+ if there are no available connections.
|
||||
|
||||
def empty?
|
||||
(@created - @que.length) >= @max
|
||||
end
|
||||
|
||||
##
|
||||
# The number of connections available on the stack.
|
||||
|
||||
def length
|
||||
@max - @created + @que.length
|
||||
end
|
||||
@ -139,6 +134,12 @@ class Bundler::ConnectionPool::TimedStack
|
||||
@que.length
|
||||
end
|
||||
|
||||
##
|
||||
# Reduce the created count
|
||||
def decrement_created
|
||||
@created -= 1 unless @created == 0
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_time
|
||||
@ -148,8 +149,17 @@ class Bundler::ConnectionPool::TimedStack
|
||||
##
|
||||
# This is an extension point for TimedStack and is called with a mutex.
|
||||
#
|
||||
# This method must returns true if a connection is available on the stack.
|
||||
# This method must returns a connection from the stack if one exists. Allows
|
||||
# subclasses with expensive match/search algorithms to avoid double-handling
|
||||
# their stack.
|
||||
def try_fetch_connection(options = nil)
|
||||
connection_stored?(options) && fetch_connection(options)
|
||||
end
|
||||
|
||||
##
|
||||
# This is an extension point for TimedStack and is called with a mutex.
|
||||
#
|
||||
# This method must returns true if a connection is available on the stack.
|
||||
def connection_stored?(options = nil)
|
||||
!@que.empty?
|
||||
end
|
||||
@ -158,7 +168,6 @@ class Bundler::ConnectionPool::TimedStack
|
||||
# This is an extension point for TimedStack and is called with a mutex.
|
||||
#
|
||||
# This method must return a connection from the stack.
|
||||
|
||||
def fetch_connection(options = nil)
|
||||
@que.pop&.first
|
||||
end
|
||||
@ -167,10 +176,8 @@ class Bundler::ConnectionPool::TimedStack
|
||||
# This is an extension point for TimedStack and is called with a mutex.
|
||||
#
|
||||
# This method must shut down all connections on the stack.
|
||||
|
||||
def shutdown_connections(options = nil)
|
||||
while connection_stored?(options)
|
||||
conn = fetch_connection(options)
|
||||
while (conn = try_fetch_connection(options))
|
||||
@created -= 1 unless @created == 0
|
||||
@shutdown_block.call(conn)
|
||||
end
|
||||
@ -181,7 +188,6 @@ class Bundler::ConnectionPool::TimedStack
|
||||
#
|
||||
# This method returns the oldest idle connection if it has been idle for more than idle_seconds.
|
||||
# This requires that the stack is kept in order of checked in time (oldest first).
|
||||
|
||||
def reserve_idle_connection(idle_seconds)
|
||||
return unless idle_connections?(idle_seconds)
|
||||
|
||||
@ -194,7 +200,6 @@ class Bundler::ConnectionPool::TimedStack
|
||||
# This is an extension point for TimedStack and is called with a mutex.
|
||||
#
|
||||
# Returns true if the first connection in the stack has been idle for more than idle_seconds
|
||||
|
||||
def idle_connections?(idle_seconds)
|
||||
connection_stored? && (current_time - @que.first.last > idle_seconds)
|
||||
end
|
||||
@ -203,7 +208,6 @@ class Bundler::ConnectionPool::TimedStack
|
||||
# This is an extension point for TimedStack and is called with a mutex.
|
||||
#
|
||||
# This method must return +obj+ to the stack.
|
||||
|
||||
def store_connection(obj, options = nil)
|
||||
@que.push [obj, current_time]
|
||||
end
|
||||
@ -213,7 +217,6 @@ class Bundler::ConnectionPool::TimedStack
|
||||
#
|
||||
# This method must create a connection if and only if the total number of
|
||||
# connections allowed has not been met.
|
||||
|
||||
def try_create(options = nil)
|
||||
unless @created == @max
|
||||
object = @create_block.call
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
class Bundler::ConnectionPool
|
||||
VERSION = "2.5.0"
|
||||
VERSION = "2.5.4"
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user