class ActiveRecord::Bogacs::FalsePool
Constants
- TIMEOUT_ERROR
def checkout_and_verify(conn)
conn.run_callbacks(:checkout) { conn.verify! } conn
end
Attributes
Public Class Methods
# File lib/active_record/bogacs/false_pool.rb, line 21 def initialize(spec) super() @spec = spec @size = nil @automatic_reconnect = nil @lock_thread = false @thread_cached_conns = ThreadSafe::Map.new @connected = ::Concurrent::AtomicBoolean.new end
Public Instance Methods
Is there an open connection that is being used for the current thread?
# File lib/active_record/bogacs/false_pool.rb, line 56 def active_connection? connection_id = connection_cache_key(current_thread) @thread_cached_conns[connection_id] end
Check-in a database connection back into the pool, indicating that you no longer need this connection.
@param conn [ActiveRecord::ConnectionAdapters::AbstractAdapter] connection object, which was obtained earlier by calling checkout
on this pool @see checkout
# File lib/active_record/bogacs/false_pool.rb, line 184 def checkin(conn, released = nil) release(conn) unless released _run_checkin_callbacks(conn) end
Check-out a database connection from the pool, indicating that you want to use it. You should call checkin
when you no longer need this.
@return [ActiveRecord::ConnectionAdapters::AbstractAdapter] @raise [ActiveRecord::ConnectionTimeoutError] no connection can be obtained from the pool
# File lib/active_record/bogacs/false_pool.rb, line 169 def checkout conn = checkout_new_connection # acquire_connection synchronize do conn.lease _run_checkout_callbacks(conn) # checkout_and_verify(conn) end conn end
@private
# File lib/active_record/bogacs/false_pool.rb, line 38 def checkout_timeout; end
Clears the cache which maps classes.
# File lib/active_record/bogacs/false_pool.rb, line 123 def clear_reloadable_connections! synchronize do @connected.make_false connections = @thread_cached_conns.values @thread_cached_conns.clear connections.each do |conn| if conn.in_use? conn.steal! checkin conn end conn.disconnect! if conn.requires_reloading? end end end
Return any checked-out connections back to the pool by threads that are no longer alive. @private AR 3.2 compatibility
# File lib/active_record/bogacs/false_pool.rb, line 153 def clear_stale_cached_connections! keys = Thread.list.find_all { |t| t.alive? }.map { |t| connection_cache_key(t) } keys = @thread_cached_conns.keys - keys keys.each do |key| if conn = @thread_cached_conns[key] checkin conn, true # no release @thread_cached_conns.delete(key) end end end
Returns true if a connection has already been opened.
# File lib/active_record/bogacs/false_pool.rb, line 84 def connected?; @connected.true? end
Retrieve the connection associated with the current thread, or call checkout
to obtain one if necessary.
connection
can be called any number of times; the connection is held in a hash keyed by the thread id.
# File lib/active_record/bogacs/false_pool.rb, line 50 def connection connection_id = connection_cache_key(current_thread) @thread_cached_conns[connection_id] ||= checkout end
@private replacement for attr_reader :connections
# File lib/active_record/bogacs/false_pool.rb, line 87 def connections; @thread_cached_conns.values end
Disconnects all connections in the pool, and clears the pool.
# File lib/active_record/bogacs/false_pool.rb, line 90 def disconnect! synchronize do @connected.make_false connections = @thread_cached_conns.values @thread_cached_conns.clear connections.each do |conn| if conn.in_use? conn.steal! checkin conn end conn.disconnect! end end end
# File lib/active_record/bogacs/false_pool.rb, line 200 def flush(minimum_idle = nil) # we do not really manage the connection pool end
# File lib/active_record/bogacs/false_pool.rb, line 204 def flush! reap flush(-1) end
@private
# File lib/active_record/bogacs/false_pool.rb, line 196 def reap # we do not really manage the connection pool - nothing to do ... end
@private attr_reader :reaper
# File lib/active_record/bogacs/false_pool.rb, line 35 def reaper; end
Signal that the thread is finished with the current connection. release_connection
releases the connection-thread association and returns the connection to the pool.
# File lib/active_record/bogacs/false_pool.rb, line 64 def release_connection(owner_thread = Thread.current) conn = @thread_cached_conns.delete(connection_cache_key(owner_thread)) checkin conn if conn end
Remove a connection from the connection pool. The connection will remain open and active but will no longer be managed by this pool.
# File lib/active_record/bogacs/false_pool.rb, line 191 def remove(conn) release(conn) end
# File lib/active_record/bogacs/false_pool.rb, line 209 def stat { connections: connections.size } end
Verify active connections and remove and disconnect connections associated with stale threads. @private AR 3.2 compatibility
# File lib/active_record/bogacs/false_pool.rb, line 143 def verify_active_connections! synchronize do clear_stale_cached_connections! @thread_cached_conns.values.each(&:verify!) end end
If a connection already exists yield it to the block. If no connection exists checkout a connection, yield it to the block, and checkin the connection when finished.
# File lib/active_record/bogacs/false_pool.rb, line 72 def with_connection connection_id = connection_cache_key unless conn = @thread_cached_conns[connection_id] conn = connection fresh_connection = true end yield conn ensure release_connection if fresh_connection end
Private Instance Methods
@raise [ActiveRecord::ConnectionTimeoutError]
# File lib/active_record/bogacs/false_pool.rb, line 218 def acquire_connection # underlying pool will poll and block if "empty" (all checked-out) #if conn = @available.poll #conn #elsif @connections.size < @size #checkout_new_connection #else #reap #@available.poll(@checkout_timeout) #end checkout_new_connection end
# File lib/active_record/bogacs/false_pool.rb, line 245 def checkout_new_connection # NOTE: automatic reconnect makes no sense for us! begin conn = new_connection rescue => e raise ConnectionTimeoutError, e.message if timeout_error?(e) && !e.is_a?(ConnectionTimeoutError) raise e end @connected.make_true conn.pool = self conn end
# File lib/active_record/bogacs/false_pool.rb, line 231 def release(conn, owner = conn.owner) thread_id = connection_cache_key(owner) unless owner.nil? thread_id ||= if @thread_cached_conns[conn_id = connection_cache_key].equal?(conn) conn_id else connections = @thread_cached_conns connections.keys.find { |k| connections[k].equal?(conn) } end @thread_cached_conns.delete_pair(thread_id, conn) if thread_id end
# File lib/active_record/bogacs/false_pool.rb, line 265 def timeout_error?(error) full_error = error.inspect # Tomcat JDBC : # ActiveRecord::JDBCError(<The driver encountered an unknown error: # org.apache.tomcat.jdbc.pool.PoolExhaustedException: # [main] Timeout: Pool empty. Unable to fetch a connection in 2 seconds, # none available[size:10; busy:10; idle:0; lastwait:2500].> # ) # C3P0 : # java.sql.SQLException: An attempt by a client to checkout a Connection has timed out. return true if full_error =~ TIMEOUT_ERROR # NOTE: not sure what to do on MRI and friends (C-pools not tested) false end