Class: ConnectionPool
- Inherits:
-
Object
- Object
- ConnectionPool
- Defined in:
- lib/connection_pool.rb
Overview
Do something in the block, that always create an adapter instance or connect to a server.
Defined Under Namespace
Classes: ConnectionTimeoutError
Constant Summary collapse
- VERSION =
'0.1.1'- DEFAULT_OPTIONS =
{ :size => 5, :timeout => 5 }
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
-
#checkin(conn) ⇒ Object
Check-in a connection back into the pool, indicating that you no longer need this connection.
-
#checkout ⇒ Object
Check-out a database connection from the pool, indicating that you want to use it.
-
#clear_stale_cached_connections! ⇒ Object
Return any checked-out connections back to the pool by threads that are no longer alive.
-
#connected? ⇒ Boolean
Returns true if a connection has already been opened.
-
#connection ⇒ Object
Retrieve the connection associated with the current thread, or call #checkout to obtain one if necessary.
-
#connection_cached? ⇒ Boolean
whether connection cached in the current thread.
-
#disconnect! ⇒ Object
Disconnects all connections in the pool, and clears the pool.
-
#initialize(options = {}, &block) ⇒ ConnectionPool
constructor
Creates a new ConnectionPool object.
-
#release_connection ⇒ Object
Signal that the thread is finished with the current connection.
-
#verify_active_connections! ⇒ Object
Verify active connections and remove and disconnect connections associated with stale threads.
-
#with_connection ⇒ Object
If a connection already exists yield it to the block.
Constructor Details
#initialize(options = {}, &block) ⇒ ConnectionPool
Creates a new ConnectionPool object. spec is a ConnectionSpecification object which describes database connection information (e.g. adapter, host name, username, password, etc), as well as the maximum size for this ConnectionPool.
The default ConnectionPool maximum size is 5.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/connection_pool.rb', line 77 def initialize( = {}, &block) = DEFAULT_OPTIONS.merge() raise ArgumentError, "Connection pool requires a block that create a new connection!" unless block @connection_block = block # The cache of reserved connections mapped to threads @reserved_connections = {} # The mutex used to synchronize pool access @connection_mutex = Monitor.new @queue = @connection_mutex.new_cond # default 5 second timeout @timeout = [:timeout] # default max pool size to 5 @size = [:size] @connections = [] @checked_out = [] end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
65 66 67 |
# File 'lib/connection_pool.rb', line 65 def end |
Instance Method Details
#checkin(conn) ⇒ Object
Check-in a connection back into the pool, indicating that you no longer need this connection.
conn: which was obtained by earlier by calling checkout on this pool.
207 208 209 210 211 212 |
# File 'lib/connection_pool.rb', line 207 def checkin(conn) @connection_mutex.synchronize do @checked_out.delete conn @queue.signal end end |
#checkout ⇒ Object
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.
This is done by either returning an existing connection, or by creating a new connection. If the maximum number of connections for this pool has already been reached, but the pool is empty (i.e. they’re all being used), then this method will wait until a thread has checked in a connection. The wait time is bounded however: if no connection can be checked out within the timeout specified for this pool, then a ConnectionTimeoutError exception will be raised.
Returns: connection instance return by the connection_block
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/connection_pool.rb', line 179 def checkout # Checkout an available connection @connection_mutex.synchronize do loop do conn = if @checked_out.size < @connections.size checkout_existing_connection elsif @connections.size < @size checkout_new_connection end return conn if conn # No connections available; wait for one if @queue.wait(@timeout) next else # try looting dead threads clear_stale_cached_connections! if @size == @checked_out.size raise ConnectionTimeoutError, "Could not obtain a connection within #{@timeout} seconds. The max pool size is currently #{@size}; consider increasing it." end end end end end |
#clear_stale_cached_connections! ⇒ Object
Return any checked-out connections back to the pool by threads that are no longer alive.
156 157 158 159 160 161 162 163 164 |
# File 'lib/connection_pool.rb', line 156 def clear_stale_cached_connections! keys = @reserved_connections.keys - Thread.list.find_all { |t| t.alive? }.map { |thread| thread.object_id } keys.each do |key| checkin @reserved_connections[key] @reserved_connections.delete(key) end end |
#connected? ⇒ Boolean
Returns true if a connection has already been opened.
129 130 131 |
# File 'lib/connection_pool.rb', line 129 def connected? !@connections.empty? end |
#connection ⇒ Object
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.
106 107 108 |
# File 'lib/connection_pool.rb', line 106 def connection @reserved_connections[current_connection_id] ||= checkout end |
#connection_cached? ⇒ Boolean
whether connection cached in the current thread
215 216 217 |
# File 'lib/connection_pool.rb', line 215 def connection_cached? !!@reserved_connections[current_connection_id] end |
#disconnect! ⇒ Object
Disconnects all connections in the pool, and clears the pool.
134 135 136 137 138 139 140 141 142 143 |
# File 'lib/connection_pool.rb', line 134 def disconnect! @reserved_connections.each do |name,conn| checkin conn end @reserved_connections = {} @connections.each do |conn| conn.disconnect! end @connections = [] end |
#release_connection ⇒ Object
Signal that the thread is finished with the current connection. #release_connection releases the connection-thread association and returns the connection to the pool.
113 114 115 116 |
# File 'lib/connection_pool.rb', line 113 def release_connection conn = @reserved_connections.delete(current_connection_id) checkin conn if conn end |
#verify_active_connections! ⇒ Object
Verify active connections and remove and disconnect connections associated with stale threads.
147 148 149 150 151 152 |
# File 'lib/connection_pool.rb', line 147 def verify_active_connections! #:nodoc: clear_stale_cached_connections! @connections.each do |connection| connection.verify! end end |
#with_connection ⇒ Object
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.
121 122 123 124 125 126 |
# File 'lib/connection_pool.rb', line 121 def with_connection fresh_connection = true unless connection_cached? yield connection ensure release_connection if fresh_connection end |