Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 483 lines (417 sloc) 16.364 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
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
12 module ConnectionAdapters
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Re…
fxn authored
13 # Connection pool base class for managing Active Record database
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
14 # connections.
15 #
a293278 @lifo Merge docrails
lifo authored
16 # == Introduction
17 #
18 # A connection pool synchronizes thread access to a limited number of
19 # database connections. The basic idea is that each thread checks out a
20 # database connection from the pool, uses that connection, and checks the
21 # connection back in. ConnectionPool is completely thread-safe, and will
22 # ensure that a connection cannot be used by two threads at the same time,
23 # as long as ConnectionPool's contract is correctly followed. It will also
24 # handle cases in which there are more threads than connections: if all
25 # connections have been checked out, and a thread tries to checkout a
26 # connection anyway, then ConnectionPool will wait until some other thread
27 # has checked in a connection.
28 #
29 # == Obtaining (checking out) a connection
30 #
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
31 # Connections can be obtained and used from a connection pool in several
32 # ways:
33 #
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Re…
fxn authored
34 # 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
35 # earlier (pre-connection-pooling). Eventually, when you're done with
36 # the connection(s) and wish it to be returned to the pool, you call
37 # 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
38 # default behavior for Active Record when used in conjunction with
39 # Action Pack's request handling cycle.
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
40 # 2. Manually check out a connection from the pool with
41 # ActiveRecord::Base.connection_pool.checkout. You are responsible for
42 # returning this connection to the pool when finished by calling
43 # ActiveRecord::Base.connection_pool.checkin(connection).
44 # 3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which
45 # obtains a connection, yields it as the sole argument to the block,
46 # and returns it to the pool after the block completes.
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
47 #
a293278 @lifo Merge docrails
lifo authored
48 # Connections in the pool are actually AbstractAdapter objects (or objects
49 # compatible with AbstractAdapter's interface).
50 #
51 # == Options
52 #
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
53 # There are two connection-pooling-related options that you can add to
54 # your database connection configuration:
55 #
56 # * +pool+: number indicating size of connection pool (default 5)
57 # * +wait_timeout+: number of seconds to block and wait for a connection
58 # 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
59 class ConnectionPool
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
60 include MonitorMixin
61
acccb72 @tenderlove column cache now lives on the connection pool
tenderlove authored
62 attr_accessor :automatic_reconnect
cccb998 @josevalim Expose connections available in the connection pool.
josevalim authored
63 attr_reader :spec, :connections
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
64
a293278 @lifo Merge docrails
lifo authored
65 # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
66 # object which describes database connection information (e.g. adapter,
67 # host name, username, password, etc), as well as the maximum size for
68 # this ConnectionPool.
69 #
70 # The default ConnectionPool maximum size is 5.
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
71 def initialize(spec)
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
72 super()
73
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
74 @spec = spec
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
75
029952e @nicksieger Extract a base class for connection pools, start to flesh out reserve…
nicksieger authored
76 # The cache of reserved connections mapped to threads
77 @reserved_connections = {}
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
78
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
79 @queue = new_cond
2a04110 fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
Hemant Kumar authored
80 @timeout = spec.config[:wait_timeout] || 5
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
81
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
82 # default max pool size to 5
83 @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
dd77733 @jeremy Timeout the connection pool monitor on ruby 1.8 only
jeremy authored
84
7db90aa @jonleighton Make it the responsibility of the connection to hold onto an ARel vis…
jonleighton authored
85 @connections = []
acccb72 @tenderlove column cache now lives on the connection pool
tenderlove authored
86 @automatic_reconnect = true
c94651f @tenderlove almost fisted
tenderlove authored
87 end
88
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
89 # Retrieve the connection associated with the current thread, or call
90 # #checkout to obtain one if necessary.
91 #
92 # #connection can be called any number of times; the connection is
93 # held in a hash keyed by the thread id.
94 def connection
879611f @tenderlove Merge pull request #6398 from pmahoney/threadsafe-connection-pool
tenderlove authored
95 synchronize do
96 @reserved_connections[current_connection_id] ||= checkout
97 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
98 end
99
cff19cf @tenderlove make active_connection? return true only if there is an open connecti…
tenderlove authored
100 # Is there an open connection that is being used for the current thread?
4211866 @tenderlove adding active_connection? to the connection pool
tenderlove authored
101 def active_connection?
879611f @tenderlove Merge pull request #6398 from pmahoney/threadsafe-connection-pool
tenderlove authored
102 synchronize do
103 @reserved_connections.fetch(current_connection_id) {
104 return false
105 }.in_use?
106 end
4211866 @tenderlove adding active_connection? to the connection pool
tenderlove authored
107 end
108
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
109 # 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
110 # #release_connection releases the connection-thread association
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
111 # and returns the connection to the pool.
3344520 @tenderlove reduce the number of times current_connection_id is called in with_co…
tenderlove authored
112 def release_connection(with_id = current_connection_id)
113 conn = @reserved_connections.delete(with_id)
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
114 checkin conn if conn
115 end
116
0034b78 @smartinez87 Remove extra white spaces on ActiveRecord docs.
smartinez87 authored
117 # 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
118 # 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
119 # connection when finished.
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
120 def with_connection
3344520 @tenderlove reduce the number of times current_connection_id is called in with_co…
tenderlove authored
121 connection_id = current_connection_id
ce3d8d6 @tenderlove Start implementing @reserved_connections in terms of connection leases.
tenderlove authored
122 fresh_connection = true unless active_connection?
5501b99 @coderrr Ensure ActiveRecord::Base.connection_pool.with_connection creates a n…
coderrr authored
123 yield connection
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
124 ensure
3344520 @tenderlove reduce the number of times current_connection_id is called in with_co…
tenderlove authored
125 release_connection(connection_id) if fresh_connection
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
126 end
127
029952e @nicksieger Extract a base class for connection pools, start to flesh out reserve…
nicksieger authored
128 # Returns true if a connection has already been opened.
129 def connected?
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
130 synchronize { @connections.any? }
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
131 end
132
a293278 @lifo Merge docrails
lifo authored
133 # 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
134 def disconnect!
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
135 synchronize do
136 @reserved_connections = {}
137 @connections.each do |conn|
138 checkin conn
139 conn.disconnect!
140 end
141 @connections = []
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
142 end
143 end
144
8f1b141 @smartinez87 Fixed punctuation errors.
smartinez87 authored
145 # Clears the cache which maps classes.
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
146 def clear_reloadable_connections!
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
147 synchronize do
148 @reserved_connections = {}
149 @connections.each do |conn|
150 checkin conn
151 conn.disconnect! if conn.requires_reloading?
152 end
153 @connections.delete_if do |conn|
154 conn.requires_reloading?
155 end
62c4e4d @ebeigarts Fix connection reloading in development mode. [#4929 state:resolved]
ebeigarts authored
156 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
157 end
158
817a07b @nicksieger More doco and class/method renames. Now have a strategy for integrati…
nicksieger authored
159 # Verify active connections and remove and disconnect connections
160 # associated with stale threads.
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
161 def verify_active_connections! #:nodoc:
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
162 synchronize do
163 clear_stale_cached_connections!
164 @connections.each do |connection|
165 connection.verify!
166 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
167 end
168 end
169
bd2f5c0 @tenderlove pushing caching and visitors down to the connection
tenderlove authored
170 def columns
171 with_connection do |c|
172 c.schema_cache.columns
173 end
174 end
175 deprecate :columns
176
177 def columns_hash
178 with_connection do |c|
179 c.schema_cache.columns_hash
180 end
181 end
182 deprecate :columns_hash
183
184 def primary_keys
185 with_connection do |c|
186 c.schema_cache.primary_keys
187 end
188 end
189 deprecate :primary_keys
190
191 def clear_cache!
192 with_connection do |c|
193 c.schema_cache.clear!
194 end
195 end
196 deprecate :clear_cache!
197
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to …
nicksieger authored
198 # Return any checked-out connections back to the pool by threads that
199 # are no longer alive.
200 def clear_stale_cached_connections!
42be67e @tenderlove unfactoring clear_stale_cached_connections!
tenderlove authored
201 keys = @reserved_connections.keys - Thread.list.find_all { |t|
202 t.alive?
203 }.map { |thread| thread.object_id }
204 keys.each do |key|
0e2477b @tenderlove Automatic closure of connections in threads is deprecated. For example
tenderlove authored
205 conn = @reserved_connections[key]
206 ActiveSupport::Deprecation.warn(<<-eowarn) if conn.in_use?
207 Database connections will not be closed automatically, please close your
208 database connection at the end of the thread by calling `close` on your
209 connection. For example: ActiveRecord::Base.connection.close
210 eowarn
211 checkin conn
42be67e @tenderlove unfactoring clear_stale_cached_connections!
tenderlove authored
212 @reserved_connections.delete(key)
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to …
nicksieger authored
213 end
214 end
215
a293278 @lifo Merge docrails
lifo authored
216 # Check-out a database connection from the pool, indicating that you want
217 # to use it. You should call #checkin when you no longer need this.
218 #
219 # This is done by either returning an existing connection, or by creating
220 # a new connection. If the maximum number of connections for this pool has
221 # already been reached, but the pool is empty (i.e. they're all being used),
222 # then this method will wait until a thread has checked in a connection.
223 # The wait time is bounded however: if no connection can be checked out
224 # within the timeout specified for this pool, then a ConnectionTimeoutError
225 # exception will be raised.
226 #
227 # Returns: an AbstractAdapter object.
228 #
229 # Raises:
230 # - ConnectionTimeoutError: no connection can be obtained from the pool
231 # within the timeout period.
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
232 def checkout
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
233 synchronize do
41563b4 @jrochkind ConnectionPool.checkout takes account of ruby using 'non-blocking con…
jrochkind authored
234 waited_time = 0
235
21eb18a @alk Fix race in ConnectionPool#checkout
alk authored
236 loop do
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
237 conn = @connections.find { |c| c.lease }
238
239 unless conn
240 if @connections.size < @size
241 conn = checkout_new_connection
242 conn.lease
243 end
244 end
245
246 if conn
247 checkout_and_verify conn
248 return conn
249 end
2a04110 fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
Hemant Kumar authored
250
41563b4 @jrochkind ConnectionPool.checkout takes account of ruby using 'non-blocking con…
jrochkind authored
251 if waited_time >= @timeout
252 raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout} (waited #{waited_time} seconds). The max pool size is currently #{@size}; consider increasing it."
253 end
254
255 # Sometimes our wait can end because a connection is available,
256 # but another thread can snatch it up first. If timeout hasn't
257 # passed but no connection is avail, looks like that happened --
258 # loop and wait again, for the time remaining on our timeout.
259 before_wait = Time.now
260 @queue.wait( [@timeout - waited_time, 0].max )
261 waited_time += (Time.now - before_wait)
2a04110 fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
Hemant Kumar authored
262
41563b4 @jrochkind ConnectionPool.checkout takes account of ruby using 'non-blocking con…
jrochkind authored
263 # Will go away in Rails 4, when we don't clean up
264 # after leaked connections automatically anymore. Right now, clean
265 # up after we've returned from a 'wait' if it looks like it's
266 # needed, then loop and try again.
267 if(active_connections.size >= @connections.size)
8343611 @alk made ConnectionPool#checkout more robust by trying to loot dead threa…
alk authored
268 clear_stale_cached_connections!
21eb18a @alk Fix race in ConnectionPool#checkout
alk authored
269 end
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
270 end
271 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
272 end
273
a293278 @lifo Merge docrails
lifo authored
274 # Check-in a database connection back into the pool, indicating that you
275 # no longer need this connection.
276 #
277 # +conn+: an AbstractAdapter object, which was obtained by earlier by
278 # calling +checkout+ on this pool.
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
279 def checkin(conn)
c606fe2 @tenderlove push synchronization in to each method. Reduces method calls and makes
tenderlove authored
280 synchronize do
57bc25c @jfirebaugh Use run_callbacks; the generated _run_<name>_callbacks method is not …
jfirebaugh authored
281 conn.run_callbacks :checkin do
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
282 conn.expire
471a394 @nicksieger Modify connection pool callbacks to be compatible w/ new style
nicksieger authored
283 @queue.signal
284 end
5f26ce6 @tenderlove make sure connections returned after close are marked as in_use
tenderlove authored
285
286 release conn
8e5e02b @nicksieger Collapse connection pool class hierarchy; YAGNI.
nicksieger authored
287 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
288 end
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
289
290 private
7db90aa @jonleighton Make it the responsibility of the connection to hold onto an ARel vis…
jonleighton authored
291
5f26ce6 @tenderlove make sure connections returned after close are marked as in_use
tenderlove authored
292 def release(conn)
e663aa3 Synchronize the ConnectionPool#release method to avoid thread safety …
Andrew Selder authored
293 synchronize do
294 thread_id = nil
295
296 if @reserved_connections[current_connection_id] == conn
297 thread_id = current_connection_id
298 else
299 thread_id = @reserved_connections.keys.find { |k|
300 @reserved_connections[k] == conn
301 }
302 end
5f26ce6 @tenderlove make sure connections returned after close are marked as in_use
tenderlove authored
303
e663aa3 Synchronize the ConnectionPool#release method to avoid thread safety …
Andrew Selder authored
304 @reserved_connections.delete thread_id if thread_id
305 end
5f26ce6 @tenderlove make sure connections returned after close are marked as in_use
tenderlove authored
306 end
307
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
308 def new_connection
bd2f5c0 @tenderlove pushing caching and visitors down to the connection
tenderlove authored
309 ActiveRecord::Base.send(spec.adapter_method, spec.config)
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
310 end
311
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to …
nicksieger authored
312 def current_connection_id #:nodoc:
f41b58d @mjtko use thread locals and an instance variable within QueryCache#BodyProx…
mjtko authored
313 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
314 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
315
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
316 def checkout_new_connection
acccb72 @tenderlove column cache now lives on the connection pool
tenderlove authored
317 raise ConnectionNotEstablished unless @automatic_reconnect
318
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
319 c = new_connection
29d2040 @tenderlove AbstractAdapter#close can be called to add the connection back to the
tenderlove authored
320 c.pool = self
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
321 @connections << c
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
322 c
a96b7d4 @nicksieger Add connection reset and verification upon each connection checkout
nicksieger authored
323 end
324
325 def checkout_and_verify(c)
471a394 @nicksieger Modify connection pool callbacks to be compatible w/ new style
nicksieger authored
326 c.run_callbacks :checkout do
327 c.verify!
328 end
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
329 c
330 end
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
331
5725e39 @tenderlove Rename `checked_out` to more descriptive `active_connections`
tenderlove authored
332 def active_connections
b72b477 @tenderlove Use connection lease to determine "checked_out" connections
tenderlove authored
333 @connections.find_all { |c| c.in_use? }
334 end
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
335 end
336
a293278 @lifo Merge docrails
lifo authored
337 # 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
338 # for keeping separate connection pools for Active Record models that connect
a293278 @lifo Merge docrails
lifo authored
339 # to different databases.
340 #
341 # For example, suppose that you have 5 models, with the following hierarchy:
342 #
343 # |
344 # +-- Book
345 # | |
346 # | +-- ScaryBook
347 # | +-- GoodBook
348 # +-- Author
349 # +-- BankAccount
350 #
351 # Suppose that Book is to connect to a separate database (i.e. one other
352 # than the default database). Then Book, ScaryBook and GoodBook will all use
353 # the same connection pool. Likewise, Author and BankAccount will use the
354 # same connection pool. However, the connection pool used by Author/BankAccount
355 # is not the same as the one used by Book/ScaryBook/GoodBook.
356 #
357 # 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
358 # ActiveRecord::Base.connection_handler. Active Record models use this to
a293278 @lifo Merge docrails
lifo authored
359 # determine that connection pool that they should use.
ca6d717 @nicksieger Deprecate allow_concurrency and make it have no effect
nicksieger authored
360 class ConnectionHandler
b952470 @tenderlove use an attr_reader for performance
tenderlove authored
361 attr_reader :connection_pools
362
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
363 def initialize(pools = {})
364 @connection_pools = pools
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
365 @class_to_pool = {}
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
366 end
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
367
368 def establish_connection(name, spec)
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
369 @connection_pools[spec] ||= ConnectionAdapters::ConnectionPool.new(spec)
370 @class_to_pool[name] = @connection_pools[spec]
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
371 end
372
25f9497 @tenderlove adding active_connections? to the connection pool for finding open co…
tenderlove authored
373 # Returns true if there are any active connections among the connection
374 # pools that the ConnectionHandler is managing.
375 def active_connections?
376 connection_pools.values.any? { |pool| pool.active_connection? }
377 end
378
bb8f4c2 @jrochkind inline docs for clear_active_connections! no longer says it cleans de…
jrochkind authored
379 # Returns any connections in use by the current thread back to the pool.
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
380 def clear_active_connections!
529c271 @nicksieger Simplify dispatcher callbacks to eliminate unnecessary stale thread p…
nicksieger authored
381 @connection_pools.each_value {|pool| pool.release_connection }
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
382 end
383
8f1b141 @smartinez87 Fixed punctuation errors.
smartinez87 authored
384 # Clears the cache which maps classes.
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
385 def clear_reloadable_connections!
386 @connection_pools.each_value {|pool| pool.clear_reloadable_connections! }
387 end
388
389 def clear_all_connections!
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
390 @connection_pools.each_value {|pool| pool.disconnect! }
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
391 end
392
393 # Verify active connections.
394 def verify_active_connections! #:nodoc:
817a07b @nicksieger More doco and class/method renames. Now have a strategy for integrati…
nicksieger authored
395 @connection_pools.each_value {|pool| pool.verify_active_connections! }
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
396 end
397
398 # Locate the connection of the nearest super class. This can be an
399 # active or defined connection: if it is the latter, it will be
400 # opened and set as the active connection for the class it was defined
401 # for (not necessarily the current class).
402 def retrieve_connection(klass) #:nodoc:
403 pool = retrieve_connection_pool(klass)
404 (pool && pool.connection) or raise ConnectionNotEstablished
405 end
406
82fcd9d @nicksieger Clean up the code, get rid of reserve/release, add some more docs
nicksieger authored
407 # Returns true if a connection that's accessible to this class has
408 # already been opened.
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
409 def connected?(klass)
0832bc6 @lifo Make sure ActiveRecord::Base.connected? doesn't raise an exception fo…
lifo authored
410 conn = retrieve_connection_pool(klass)
a4458f5 @tenderlove removing useless ternary
tenderlove authored
411 conn && conn.connected?
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
412 end
413
414 # Remove the connection for this class. This will close the active
415 # connection and the defined connection (if they exist). The result
416 # can be used as an argument for establish_connection, for easily
417 # re-establishing the connection.
418 def remove_connection(klass)
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
419 pool = @class_to_pool.delete(klass.name)
04ef434 @tenderlove only test for existence of +pool+ once
tenderlove authored
420 return nil unless pool
421
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
422 @connection_pools.delete pool.spec
acccb72 @tenderlove column cache now lives on the connection pool
tenderlove authored
423 pool.automatic_reconnect = false
04ef434 @tenderlove only test for existence of +pool+ once
tenderlove authored
424 pool.disconnect!
425 pool.spec.config
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHan…
nicksieger authored
426 end
427
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
428 def retrieve_connection_pool(klass)
ffb218c @tenderlove pools are 1:1 with spec now rather than 1:1 with class
tenderlove authored
429 pool = @class_to_pool[klass.name]
3007545 @nicksieger Minor tweak to retrieve_connection_pool -- recurse instead of loop
nicksieger authored
430 return pool if pool
431 return nil if ActiveRecord::Base == klass
432 retrieve_connection_pool klass.superclass
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implement…
nicksieger authored
433 end
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
434 end
1b22071 @josh Ensure ActiveRecord session store's connections are checked in after …
josh authored
435
436 class ConnectionManagement
e524609 @tenderlove proxy body responses so we close database connections after body is f…
tenderlove authored
437 class Proxy # :nodoc:
438 attr_reader :body, :testing
439
440 def initialize(body, testing = false)
441 @body = body
442 @testing = testing
443 end
444
5044420 @stevehodgkiss Fix inconsistencies by being polite to the wrapped body. Needed for R…
stevehodgkiss authored
445 def method_missing(method_sym, *arguments, &block)
446 @body.send(method_sym, *arguments, &block)
447 end
448
449 def respond_to?(method_sym, include_private = false)
450 super || @body.respond_to?(method_sym)
451 end
452
e524609 @tenderlove proxy body responses so we close database connections after body is f…
tenderlove authored
453 def each(&block)
454 body.each(&block)
455 end
456
457 def close
458 body.close if body.respond_to?(:close)
459
460 # Don't return connection (and perform implicit rollback) if
461 # this request is a part of integration test
462 ActiveRecord::Base.clear_active_connections! unless testing
463 end
464 end
465
1b22071 @josh Ensure ActiveRecord session store's connections are checked in after …
josh authored
466 def initialize(app)
467 @app = app
468 end
469
470 def call(env)
c7b7c6a @tenderlove make sure that active connections are not cleared during test when an…
tenderlove authored
471 testing = env.key?('rack.test')
472
e524609 @tenderlove proxy body responses so we close database connections after body is f…
tenderlove authored
473 status, headers, body = @app.call(env)
474
c7b7c6a @tenderlove make sure that active connections are not cleared during test when an…
tenderlove authored
475 [status, headers, Proxy.new(body, testing)]
3b2a032 @tenderlove clearing active connections in the ConnectionManagement middleware if…
tenderlove authored
476 rescue
c7b7c6a @tenderlove make sure that active connections are not cleared during test when an…
tenderlove authored
477 ActiveRecord::Base.clear_active_connections! unless testing
3b2a032 @tenderlove clearing active connections in the ConnectionManagement middleware if…
tenderlove authored
478 raise
1b22071 @josh Ensure ActiveRecord session store's connections are checked in after …
josh authored
479 end
480 end
6edaa26 @nicksieger Initial conversion to connection pool
nicksieger authored
481 end
21eb18a @alk Fix race in ConnectionPool#checkout
alk authored
482 end
Something went wrong with that request. Please try again.