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