Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 429 lines (375 sloc) 14.823 kb
d869298 @raggi Don't depend on rubygems loading thread (for Mutex)
raggi authored
1 require 'thread'
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
2 require 'monitor'
50cd4bd @nicksieger Introduce synchronization around connection pool access
nicksieger authored
3 require 'set'
bd2f5c0 @tenderlove pushing caching and visitors down to the connection
tenderlove authored
4 require 'active_support/core_ext/module/deprecation'
50cd4bd @nicksieger Introduce synchronization around connection pool access
nicksieger authored
5
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
6 module ActiveRecord
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
7 # Raised when a connection could not be obtained within the connection
8 # acquisition timeout period.
9 class ConnectionTimeoutError < ConnectionNotEstablished
10 end
11
cceabe0 @tenderlove raise a pull full error when the connection pool is full and no conne…
tenderlove authored
12 # Raised when a connection pool is full and another connection is requested
13 class PoolFullError < ConnectionNotEstablished
14 def initialize size, timeout
15 super("Connection pool of size #{size} and timeout #{timeout}s is full")
16 end
17 end
18
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
19 module ConnectionAdapters
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Re…
fxn authored
20 # Connection pool base class for managing Active Record database
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
21 # connections.
22 #
a293278 @lifo Merge docrails
lifo authored
23 # == Introduction
24 #
25 # A connection pool synchronizes thread access to a limited number of
26 # database connections. The basic idea is that each thread checks out a
27 # database connection from the pool, uses that connection, and checks the
28 # connection back in. ConnectionPool is completely thread-safe, and will
29 # ensure that a connection cannot be used by two threads at the same time,
30 # as long as ConnectionPool's contract is correctly followed. It will also
31 # handle cases in which there are more threads than connections: if all
32 # connections have been checked out, and a thread tries to checkout a
33 # connection anyway, then ConnectionPool will wait until some other thread
34 # has checked in a connection.
35 #
36 # == Obtaining (checking out) a connection
37 #
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
38 # Connections can be obtained and used from a connection pool in several
39 # ways:
40 #
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Re…
fxn authored
41 # 1. Simply use ActiveRecord::Base.connection as with Active Record 2.1 and
817a07b @nicksieger More doco and class/method renames. Now have a strategy for integrati…
nicksieger authored
42 # earlier (pre-connection-pooling). Eventually, when you're done with
43 # the connection(s) and wish it to be returned to the pool, you call
44 # ActiveRecord::Base.clear_active_connections!. This will be the
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Re…
fxn authored
45 # default behavior for Active Record when used in conjunction with
46 # Action Pack's request handling cycle.
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
47 # 2. Manually check out a connection from the pool with
48 # ActiveRecord::Base.connection_pool.checkout. You are responsible for
49 # returning this connection to the pool when finished by calling
50 # ActiveRecord::Base.connection_pool.checkin(connection).
51 # 3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which
52 # obtains a connection, yields it as the sole argument to the block,
53 # and returns it to the pool after the block completes.
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
54 #
a293278 @lifo Merge docrails
lifo authored
55 # Connections in the pool are actually AbstractAdapter objects (or objects
56 # compatible with AbstractAdapter's interface).
57 #
58 # == Options
59 #
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
60 # There are two connection-pooling-related options that you can add to
61 # your database connection configuration:
62 #
63 # * +pool+: number indicating size of connection pool (default 5)
64 # * +wait_timeout+: number of seconds to block and wait for a connection
65 # before giving up and raising a timeout error (default 5 seconds).
817a07b @nicksieger More doco and class/method renames. Now have a strategy for integrati…
nicksieger authored
66 class ConnectionPool
41c24eb @tenderlove each connection pool has a reaper
tenderlove authored
67 # Every +frequency+ seconds, the reaper will call +reap+ on +pool+.
68 # A reaper instantiated with a nil frequency will never reap the
69 # connection pool.
641b43e @tenderlove updating the reaping frequency documentation
tenderlove authored
70 #
71 # Configure the frequency by setting "reaping_frequency" in your
72 # database yaml file.
cde7692 @tenderlove introduce a timer class for reaping connections
tenderlove authored
73 class Reaper
74 attr_reader :pool, :frequency
75
76 def initialize(pool, frequency)
77 @pool = pool
78 @frequency = frequency
79 end
80
59f2696 @tenderlove rename start to run and use Thread.pass rather than sleeping to sched…
tenderlove authored
81 def run
cde7692 @tenderlove introduce a timer class for reaping connections
tenderlove authored
82 return unless frequency
83 Thread.new(frequency, pool) { |t, p|
84 while true
85 sleep t
86 p.reap
87 end
88 }
89 end
90 end
91
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
92 include MonitorMixin
93
17ff88c @tenderlove connections can be removed from the pool
tenderlove authored
94 attr_accessor :automatic_reconnect, :timeout
41c24eb @tenderlove each connection pool has a reaper
tenderlove authored
95 attr_reader :spec, :connections, :size, :reaper
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
96
a293278 @lifo Merge docrails
lifo authored
97 # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
98 # object which describes database connection information (e.g. adapter,
99 # host name, username, password, etc), as well as the maximum size for
100 # this ConnectionPool.
101 #
102 # The default ConnectionPool maximum size is 5.
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
103 def initialize(spec)
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
104 super()
105
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
106 @spec = spec
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
107
029952e @nicksieger Extract a base class for connection pools, start to flesh out reserve…
nicksieger authored
108 # The cache of reserved connections mapped to threads
109 @reserved_connections = {}
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
110
2a04110 fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
Hemant Kumar authored
111 @timeout = spec.config[:wait_timeout] || 5
41c24eb @tenderlove each connection pool has a reaper
tenderlove authored
112 @reaper = Reaper.new self, spec.config[:reaping_frequency]
59f2696 @tenderlove rename start to run and use Thread.pass rather than sleeping to sched…
tenderlove authored
113 @reaper.run
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
114
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
115 # default max pool size to 5
116 @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
117
7db90aa @jonleighton Make it the responsibility of the connection to hold onto an ARel vis…
jonleighton authored
118 @connections = []
acccb72 @tenderlove column cache now lives on the connection pool
tenderlove authored
119 @automatic_reconnect = true
c94651f @tenderlove almost fisted
tenderlove authored
120 end
121
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
122 # Retrieve the connection associated with the current thread, or call
123 # #checkout to obtain one if necessary.
124 #
125 # #connection can be called any number of times; the connection is
126 # held in a hash keyed by the thread id.
127 def connection
072cd60 @tenderlove refactor if / else to ||=
tenderlove authored
128 @reserved_connections[current_connection_id] ||= checkout
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
129 end
130
4211866 @tenderlove adding active_connection? to the connection pool
tenderlove authored
131 # Check to see if there is an active connection in this connection
132 # pool.
133 def active_connection?
ce3d8d6 @tenderlove Start implementing @reserved_connections in terms of connection leases.
tenderlove authored
134 active_connections.any?
4211866 @tenderlove adding active_connection? to the connection pool
tenderlove authored
135 end
136
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
137 # Signal that the thread is finished with the current connection.
817a07b @nicksieger More doco and class/method renames. Now have a strategy for integrati…
nicksieger authored
138 # #release_connection releases the connection-thread association
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
139 # and returns the connection to the pool.
3344520 @tenderlove reduce the number of times current_connection_id is called in with_co…
tenderlove authored
140 def release_connection(with_id = current_connection_id)
141 conn = @reserved_connections.delete(with_id)
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
142 checkin conn if conn
143 end
144
0034b78 @smartinez87 Remove extra white spaces on ActiveRecord docs.
smartinez87 authored
145 # If a connection already exists yield it to the block. If no connection
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
146 # exists checkout a connection, yield it to the block, and checkin the
5501b99 @coderrr Ensure ActiveRecord::Base.connection_pool.with_connection creates a n…
coderrr authored
147 # connection when finished.
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
148 def with_connection
3344520 @tenderlove reduce the number of times current_connection_id is called in with_co…
tenderlove authored
149 connection_id = current_connection_id
ce3d8d6 @tenderlove Start implementing @reserved_connections in terms of connection leases.
tenderlove authored
150 fresh_connection = true unless active_connection?
5501b99 @coderrr Ensure ActiveRecord::Base.connection_pool.with_connection creates a n…
coderrr authored
151 yield connection
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
152 ensure
3344520 @tenderlove reduce the number of times current_connection_id is called in with_co…
tenderlove authored
153 release_connection(connection_id) if fresh_connection
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
154 end
155
029952e @nicksieger Extract a base class for connection pools, start to flesh out reserve…
nicksieger authored
156 # Returns true if a connection has already been opened.
157 def connected?
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
158 synchronize { @connections.any? }
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
159 end
160
a293278 @lifo Merge docrails
lifo authored
161 # Disconnects all connections in the pool, and clears the pool.
029952e @nicksieger Extract a base class for connection pools, start to flesh out reserve…
nicksieger authored
162 def disconnect!
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
163 synchronize do
164 @reserved_connections = {}
165 @connections.each do |conn|
166 checkin conn
167 conn.disconnect!
168 end
169 @connections = []
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
170 end
171 end
172
8f1b141 @smartinez87 Fixed punctuation errors.
smartinez87 authored
173 # Clears the cache which maps classes.
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
174 def clear_reloadable_connections!
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
175 synchronize do
176 @reserved_connections = {}
177 @connections.each do |conn|
178 checkin conn
179 conn.disconnect! if conn.requires_reloading?
180 end
181 @connections.delete_if do |conn|
182 conn.requires_reloading?
183 end
62c4e4d @ebeigarts Fix connection reloading in development mode. [#4929 state:resolved]
ebeigarts authored
184 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
185 end
186
817a07b @nicksieger More doco and class/method renames. Now have a strategy for integrati…
nicksieger authored
187 # Verify active connections and remove and disconnect connections
188 # associated with stale threads.
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
189 def verify_active_connections! #:nodoc:
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
190 synchronize do
191 @connections.each do |connection|
192 connection.verify!
193 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
194 end
195 end
196
cceabe0 @tenderlove raise a pull full error when the connection pool is full and no conne…
tenderlove authored
197 def clear_stale_cached_connections! # :nodoc:
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to …
nicksieger authored
198 end
6769293 @tenderlove connections must be checked in at the end of a thread
tenderlove authored
199 deprecate :clear_stale_cached_connections!
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to …
nicksieger authored
200
a293278 @lifo Merge docrails
lifo authored
201 # Check-out a database connection from the pool, indicating that you want
202 # to use it. You should call #checkin when you no longer need this.
203 #
cceabe0 @tenderlove raise a pull full error when the connection pool is full and no conne…
tenderlove authored
204 # This is done by either returning and leasing existing connection, or by
205 # creating a new connection and leasing it.
206 #
207 # If all connections are leased and the pool is at capacity (meaning the
208 # number of currently leased connections is greater than or equal to the
209 # size limit set), an ActiveRecord::PoolFullError exception will be raised.
a293278 @lifo Merge docrails
lifo authored
210 #
211 # Returns: an AbstractAdapter object.
212 #
213 # Raises:
cceabe0 @tenderlove raise a pull full error when the connection pool is full and no conne…
tenderlove authored
214 # - PoolFullError: no connection can be obtained from the pool.
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
215 def checkout
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
216 # Checkout an available connection
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
217 synchronize do
cceabe0 @tenderlove raise a pull full error when the connection pool is full and no conne…
tenderlove authored
218 # Try to find a connection that hasn't been leased, and lease it
219 conn = connections.find { |c| c.lease }
2a04110 fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
Hemant Kumar authored
220
5dc7257 @tenderlove refactor checking out the connection
tenderlove authored
221 # If all connections were leased, and we have room to expand,
222 # create a new connection and lease it.
cceabe0 @tenderlove raise a pull full error when the connection pool is full and no conne…
tenderlove authored
223 if !conn && connections.size < size
5dc7257 @tenderlove refactor checking out the connection
tenderlove authored
224 conn = checkout_new_connection
225 conn.lease
df9de6f @tenderlove infinite loop is no longer necessary
tenderlove authored
226 end
2a04110 fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
Hemant Kumar authored
227
df9de6f @tenderlove infinite loop is no longer necessary
tenderlove authored
228 if conn
229 checkout_and_verify conn
230 else
cceabe0 @tenderlove raise a pull full error when the connection pool is full and no conne…
tenderlove authored
231 raise PoolFullError.new(size, timeout)
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
232 end
233 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
234 end
235
a293278 @lifo Merge docrails
lifo authored
236 # Check-in a database connection back into the pool, indicating that you
237 # no longer need this connection.
238 #
239 # +conn+: an AbstractAdapter object, which was obtained by earlier by
240 # calling +checkout+ on this pool.
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
241 def checkin(conn)
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
242 synchronize do
57bc25c @jfirebaugh Use run_callbacks; the generated _run_<name>_callbacks method is not …
jfirebaugh authored
243 conn.run_callbacks :checkin do
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
244 conn.expire
471a394 @nicksieger Modify connection pool callbacks to be compatible w/ new style
nicksieger authored
245 end
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
246 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
247 end
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
248
17ff88c @tenderlove connections can be removed from the pool
tenderlove authored
249 # Remove a connection from the connection pool. The connection will
250 # remain open and active but will no longer be managed by this pool.
251 def remove(conn)
252 synchronize do
253 @connections.delete conn
e060cf0 @tenderlove deal with removing connections associated with the current thread
tenderlove authored
254
255 # FIXME: we might want to store the key on the connection so that removing
256 # from the reserved hash will be a little easier.
257 thread_id = @reserved_connections.keys.find { |k|
258 @reserved_connections[k] == conn
259 }
260 @reserved_connections.delete thread_id if thread_id
17ff88c @tenderlove connections can be removed from the pool
tenderlove authored
261 end
262 end
263
86729eb @tenderlove connections can be reaped via the `reap` method
tenderlove authored
264 # Removes dead connections from the pool. A dead connection can occur
265 # if a programmer forgets to close a connection at the end of a thread
266 # or a thread dies unexpectedly.
267 def reap
268 synchronize do
269 stale = Time.now - @timeout
270 connections.dup.each do |conn|
b1ac881 @tenderlove connections are only removed if they are inactve
tenderlove authored
271 remove conn if conn.in_use? && stale > conn.last_use && !conn.active?
86729eb @tenderlove connections can be reaped via the `reap` method
tenderlove authored
272 end
273 end
274 end
275
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
276 private
7db90aa @jonleighton Make it the responsibility of the connection to hold onto an ARel vis…
jonleighton authored
277
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
278 def new_connection
bd2f5c0 @tenderlove pushing caching and visitors down to the connection
tenderlove authored
279 ActiveRecord::Base.send(spec.adapter_method, spec.config)
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
280 end
281
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to …
nicksieger authored
282 def current_connection_id #:nodoc:
f41b58d @mjtko use thread locals and an instance variable within QueryCache#BodyProx…
mjtko authored
283 ActiveRecord::Base.connection_id ||= Thread.current.object_id
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
284 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
285
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
286 def checkout_new_connection
acccb72 @tenderlove column cache now lives on the connection pool
tenderlove authored
287 raise ConnectionNotEstablished unless @automatic_reconnect
288
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
289 c = new_connection
29d2040 @tenderlove AbstractAdapter#close can be called to add the connection back to the
tenderlove authored
290 c.pool = self
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
291 @connections << c
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
292 c
a96b7d4 @nicksieger Add connection reset and verification upon each connection checkout
nicksieger authored
293 end
294
295 def checkout_and_verify(c)
471a394 @nicksieger Modify connection pool callbacks to be compatible w/ new style
nicksieger authored
296 c.run_callbacks :checkout do
297 c.verify!
298 end
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
299 c
300 end
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
301
5725e39 @tenderlove Rename `checked_out` to more descriptive `active_connections`
tenderlove authored
302 def active_connections
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
303 @connections.find_all { |c| c.in_use? }
304 end
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
305 end
306
a293278 @lifo Merge docrails
lifo authored
307 # ConnectionHandler is a collection of ConnectionPool objects. It is used
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Re…
fxn authored
308 # for keeping separate connection pools for Active Record models that connect
a293278 @lifo Merge docrails
lifo authored
309 # to different databases.
310 #
311 # For example, suppose that you have 5 models, with the following hierarchy:
312 #
313 # |
314 # +-- Book
315 # | |
316 # | +-- ScaryBook
317 # | +-- GoodBook
318 # +-- Author
319 # +-- BankAccount
320 #
321 # Suppose that Book is to connect to a separate database (i.e. one other
322 # than the default database). Then Book, ScaryBook and GoodBook will all use
323 # the same connection pool. Likewise, Author and BankAccount will use the
324 # same connection pool. However, the connection pool used by Author/BankAccount
325 # is not the same as the one used by Book/ScaryBook/GoodBook.
326 #
327 # Normally there is only a single ConnectionHandler instance, accessible via
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Re…
fxn authored
328 # ActiveRecord::Base.connection_handler. Active Record models use this to
a293278 @lifo Merge docrails
lifo authored
329 # determine that connection pool that they should use.
ca6d717 @nicksieger Deprecate allow_concurrency and make it have no effect
nicksieger authored
330 class ConnectionHandler
b952470 @tenderlove use an attr_reader for performance
tenderlove authored
331 attr_reader :connection_pools
332
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
333 def initialize(pools = {})
334 @connection_pools = pools
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
335 @class_to_pool = {}
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
336 end
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
337
338 def establish_connection(name, spec)
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
339 @connection_pools[spec] ||= ConnectionAdapters::ConnectionPool.new(spec)
340 @class_to_pool[name] = @connection_pools[spec]
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
341 end
342
25f9497 @tenderlove adding active_connections? to the connection pool for finding open co…
tenderlove authored
343 # Returns true if there are any active connections among the connection
344 # pools that the ConnectionHandler is managing.
345 def active_connections?
346 connection_pools.values.any? { |pool| pool.active_connection? }
347 end
348
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to …
nicksieger authored
349 # Returns any connections in use by the current thread back to the pool,
350 # and also returns connections to the pool cached by threads that are no
351 # longer alive.
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
352 def clear_active_connections!
529c271 @nicksieger Simplify dispatcher callbacks to eliminate unnecessary stale thread p…
nicksieger authored
353 @connection_pools.each_value {|pool| pool.release_connection }
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
354 end
355
8f1b141 @smartinez87 Fixed punctuation errors.
smartinez87 authored
356 # Clears the cache which maps classes.
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
357 def clear_reloadable_connections!
358 @connection_pools.each_value {|pool| pool.clear_reloadable_connections! }
359 end
360
361 def clear_all_connections!
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
362 @connection_pools.each_value {|pool| pool.disconnect! }
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
363 end
364
365 # Verify active connections.
366 def verify_active_connections! #:nodoc:
817a07b @nicksieger More doco and class/method renames. Now have a strategy for integrati…
nicksieger authored
367 @connection_pools.each_value {|pool| pool.verify_active_connections! }
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
368 end
369
370 # Locate the connection of the nearest super class. This can be an
371 # active or defined connection: if it is the latter, it will be
372 # opened and set as the active connection for the class it was defined
373 # for (not necessarily the current class).
374 def retrieve_connection(klass) #:nodoc:
375 pool = retrieve_connection_pool(klass)
376 (pool && pool.connection) or raise ConnectionNotEstablished
377 end
378
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
379 # Returns true if a connection that's accessible to this class has
380 # already been opened.
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
381 def connected?(klass)
0832bc6 @lifo Make sure ActiveRecord::Base.connected? doesn't raise an exception fo…
lifo authored
382 conn = retrieve_connection_pool(klass)
a4458f5 @tenderlove removing useless ternary
tenderlove authored
383 conn && conn.connected?
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
384 end
385
386 # Remove the connection for this class. This will close the active
387 # connection and the defined connection (if they exist). The result
388 # can be used as an argument for establish_connection, for easily
389 # re-establishing the connection.
390 def remove_connection(klass)
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
391 pool = @class_to_pool.delete(klass.name)
04ef434 @tenderlove only test for existence of +pool+ once
tenderlove authored
392 return nil unless pool
393
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
394 @connection_pools.delete pool.spec
acccb72 @tenderlove column cache now lives on the connection pool
tenderlove authored
395 pool.automatic_reconnect = false
04ef434 @tenderlove only test for existence of +pool+ once
tenderlove authored
396 pool.disconnect!
397 pool.spec.config
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
398 end
399
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
400 def retrieve_connection_pool(klass)
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
401 pool = @class_to_pool[klass.name]
3007545 @nicksieger Minor tweak to retrieve_connection_pool -- recurse instead of loop
nicksieger authored
402 return pool if pool
dae7b65 @jonleighton Support establishing connection on ActiveRecord::Model.
jonleighton authored
403 return nil if ActiveRecord::Model == klass
7293cac @jonleighton Extract common logic into a method
jonleighton authored
404 retrieve_connection_pool klass.active_record_super
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
405 end
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
406 end
1b22071 @josh Ensure ActiveRecord session store's connections are checked in after …
josh authored
407
408 class ConnectionManagement
409 def initialize(app)
410 @app = app
411 end
412
413 def call(env)
c7b7c6a @tenderlove make sure that active connections are not cleared during test when an…
tenderlove authored
414 testing = env.key?('rack.test')
415
2b81240 @lest use Rack::BodyProxy in activerecord middlewares
lest authored
416 response = @app.call(env)
417 response[2] = ::Rack::BodyProxy.new(response[2]) do
418 ActiveRecord::Base.clear_active_connections! unless testing
419 end
e524609 @tenderlove proxy body responses so we close database connections after body is f…
tenderlove authored
420
2b81240 @lest use Rack::BodyProxy in activerecord middlewares
lest authored
421 response
3b2a032 @tenderlove clearing active connections in the ConnectionManagement middleware if…
tenderlove authored
422 rescue
c7b7c6a @tenderlove make sure that active connections are not cleared during test when an…
tenderlove authored
423 ActiveRecord::Base.clear_active_connections! unless testing
3b2a032 @tenderlove clearing active connections in the ConnectionManagement middleware if…
tenderlove authored
424 raise
1b22071 @josh Ensure ActiveRecord session store's connections are checked in after …
josh authored
425 end
426 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
427 end
21eb18a @alk Fix race in ConnectionPool#checkout
alk authored
428 end
Something went wrong with that request. Please try again.