Class: RDBI::Pool
- Inherits:
-
Object
- Object
- RDBI::Pool
- Extended by:
- Enumerable
- Includes:
- Enumerable
- Defined in:
- lib/rdbi/pool.rb
Overview
RDBI::Pool - Connection Pooling.
Pools are named resources that consist of N concurrent connections which all have the same properties. Many group actions can be performed on them, such as disconnecting the entire lot.
RDBI::Pool itself has a global accessor, by way of RDBI::Pool::[]
, that can access these pools by name. Alternatively, you may access them through the RDBI.pool interface.
Pools are thread-safe and are capable of being resized without disconnecting the culled database handles.
Instance Attribute Summary collapse
-
#handles ⇒ Object
readonly
a list of the pool handles for this object.
-
#last_index ⇒ Object
readonly
the last index corresponding to the latest allocation request.
-
#max ⇒ Object
readonly
the maximum number of items this pool can hold.
-
#mutex ⇒ Object
readonly
the Mutex for this pool.
Class Method Summary collapse
-
.[](name) ⇒ Object
Retrieves a pool object for the name, or nothing if it does not exist.
-
.[]=(name, value) ⇒ Object
Sets the pool for the name.
-
.each ⇒ Object
Iterate each pool and get the name of the pool (as a symbol) and the value as a Pool object.
-
.keys ⇒ Object
obtain the names of each pool.
- .mutex ⇒ Object
-
.values ⇒ Object
obtain the pool objects of each pool.
Instance Method Summary collapse
-
#add_connection ⇒ Object
Add a connection, connecting automatically with the connect arguments supplied to the constructor.
-
#disconnect ⇒ Object
Disconnect all database handles.
-
#each ⇒ Object
Obtain each database handle in the pool.
-
#get_dbh ⇒ Object
Obtain a database handle from the pool.
-
#initialize(name, connect_args, max = 5) ⇒ Pool
constructor
Creates a new pool.
-
#ping ⇒ Object
Ping all database connections and average out the amount.
-
#reconnect ⇒ Object
Unconditionally reconnect all database handles.
-
#reconnect_if_disconnected ⇒ Object
Only reconnect the database handles that have not been already connected.
-
#remove(dbh) ⇒ Object
Remove a specific connection.
-
#resize(max = 5) ⇒ Object
Resize the pool.
-
#up ⇒ Object
Asserts that all the pooled handles are connected.
Constructor Details
#initialize(name, connect_args, max = 5) ⇒ Pool
Creates a new pool.
-
name: the name of this pool, which will be used to find it in the global accessor.
-
connect_args: an array of arguments that would be passed to RDBI.connect, including the driver name.
-
max: the maximum number of connections to deal with.
Usage:
Pool.new(:fart, [:SQLite3, :database => “/tmp/foo.db”]) Pool.new(:quux, { :database => :SQLite3, :database => “:memory:” })
87 88 89 90 91 92 93 94 95 |
# File 'lib/rdbi/pool.rb', line 87 def initialize(name, connect_args, max=5) @handles = [] @connect_args = connect_args munge_connect_args! @max = max @last_index = 0 @mutex = Mutex.new self.class[name] = self end |
Instance Attribute Details
#handles ⇒ Object (readonly)
a list of the pool handles for this object. Do not manipulate this directly.
68 69 70 |
# File 'lib/rdbi/pool.rb', line 68 def handles @handles end |
#last_index ⇒ Object (readonly)
the last index corresponding to the latest allocation request.
70 71 72 |
# File 'lib/rdbi/pool.rb', line 70 def last_index @last_index end |
#max ⇒ Object (readonly)
the maximum number of items this pool can hold. should only be altered by resize.
72 73 74 |
# File 'lib/rdbi/pool.rb', line 72 def max @max end |
#mutex ⇒ Object (readonly)
the Mutex for this pool.
74 75 76 |
# File 'lib/rdbi/pool.rb', line 74 def mutex @mutex end |
Class Method Details
.[](name) ⇒ Object
Retrieves a pool object for the name, or nothing if it does not exist.
43 44 45 46 47 48 |
# File 'lib/rdbi/pool.rb', line 43 def [](name) mutex.synchronize do @pools ||= { } @pools[name.to_sym] end end |
.[]=(name, value) ⇒ Object
Sets the pool for the name. This is not recommended for end-user code.
53 54 55 56 57 58 |
# File 'lib/rdbi/pool.rb', line 53 def []=(name, value) mutex.synchronize do @pools ||= { } @pools[name.to_sym] = value end end |
.each ⇒ Object
Iterate each pool and get the name of the pool (as a symbol) and the value as a Pool object.
24 25 26 27 28 |
# File 'lib/rdbi/pool.rb', line 24 def each @pools.each do |key, value| yield(key, value) end end |
.keys ⇒ Object
obtain the names of each pool.
31 32 33 |
# File 'lib/rdbi/pool.rb', line 31 def keys @pools.keys end |
.mutex ⇒ Object
60 61 62 |
# File 'lib/rdbi/pool.rb', line 60 def mutex @mutex end |
.values ⇒ Object
obtain the pool objects of each pool.
36 37 38 |
# File 'lib/rdbi/pool.rb', line 36 def values @pools.values end |
Instance Method Details
#add_connection ⇒ Object
Add a connection, connecting automatically with the connect arguments supplied to the constructor.
157 158 159 |
# File 'lib/rdbi/pool.rb', line 157 def add_connection add(RDBI.connect(*@connect_args)) end |
#disconnect ⇒ Object
Disconnect all database handles.
148 149 150 151 152 |
# File 'lib/rdbi/pool.rb', line 148 def disconnect mutex.synchronize do @handles.each(&:disconnect) end end |
#each ⇒ Object
Obtain each database handle in the pool.
98 99 100 |
# File 'lib/rdbi/pool.rb', line 98 def each @handles.each { |dbh| yield dbh } end |
#get_dbh ⇒ Object
Obtain a database handle from the pool. Ordering is round robin.
A new connection may be created if it fills in the pool where a previously empty object existed. Additionally, if the current database handle is disconnected, it will be reconnected.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/rdbi/pool.rb', line 209 def get_dbh mutex.synchronize do if @last_index >= @max @last_index = 0 end # XXX this is longhand for "make sure it's connected before we hand it # off" if @handles[@last_index] and !@handles[@last_index].connected? @handles[@last_index].reconnect elsif !@handles[@last_index] @handles[@last_index] = RDBI.connect(*@connect_args) end dbh = @handles[@last_index] @last_index += 1 dbh end end |
#ping ⇒ Object
Ping all database connections and average out the amount.
Any disconnected handles will be reconnected before this operation starts.
107 108 109 110 111 112 |
# File 'lib/rdbi/pool.rb', line 107 def ping reconnect_if_disconnected mutex.synchronize do @handles.inject(1) { |sum,dbh| sum + (dbh.ping || 1) } / @handles.size end end |
#reconnect ⇒ Object
Unconditionally reconnect all database handles.
130 131 132 133 134 |
# File 'lib/rdbi/pool.rb', line 130 def reconnect mutex.synchronize do @handles.each { |dbh| dbh.reconnect } end end |
#reconnect_if_disconnected ⇒ Object
Only reconnect the database handles that have not been already connected.
138 139 140 141 142 143 144 |
# File 'lib/rdbi/pool.rb', line 138 def reconnect_if_disconnected mutex.synchronize do @handles.each do |dbh| dbh.reconnect unless dbh.connected? end end end |
#remove(dbh) ⇒ Object
Remove a specific connection. If this connection does not exist in the pool already, nothing will occur.
This database object is not disconnected – it is your responsibility to do so.
167 168 169 170 171 |
# File 'lib/rdbi/pool.rb', line 167 def remove(dbh) mutex.synchronize do @handles.reject! { |x| x.object_id == dbh.object_id } end end |
#resize(max = 5) ⇒ Object
Resize the pool. If the new pool size is smaller, connections will be forcibly removed, preferring disconnected handles over connected ones.
No database connections are disconnected.
Returns the handles that were removed, if any.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/rdbi/pool.rb', line 181 def resize(max=5) mutex.synchronize do in_pool = @handles.select(&:connected?) unless (in_pool.size >= max) disconnected = @handles.select { |x| !x.connected? } if disconnected.size > 0 in_pool += disconnected[0..(max - in_pool.size - 1)] end else in_pool = in_pool[0..(max-1)] end rejected = @handles - in_pool @max = max @handles = in_pool rejected end end |
#up ⇒ Object
Asserts that all the pooled handles are connected. Returns true or false depending on the result of that assertion.
118 119 120 121 122 123 124 125 126 |
# File 'lib/rdbi/pool.rb', line 118 def up alive = false mutex.synchronize do alive = @handles.select { |x| x.ping.nil? }.empty? end return alive end |