activerecord-bogacs 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +32 -34
- data/LICENSE.txt +1 -1
- data/README.md +9 -5
- data/lib/active_record/bogacs.rb +3 -54
- data/lib/active_record/bogacs/autoload.rb +10 -0
- data/lib/active_record/bogacs/default_pool.rb +31 -42
- data/lib/active_record/bogacs/false_pool.rb +8 -20
- data/lib/active_record/bogacs/pool_support.rb +0 -1
- data/lib/active_record/bogacs/reaper.rb +4 -6
- data/lib/active_record/bogacs/shareable_pool.rb +1 -1
- data/lib/active_record/bogacs/validator.rb +6 -6
- data/lib/active_record/bogacs/version.rb +2 -2
- data/lib/active_record/connection_adapters/pool_class.rb +44 -0
- data/test/test_helper.rb +2 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8d7d0cf56d16097d5faadc25e31228e1e6b6a1040703aa0fed0fd29a49d23622
|
4
|
+
data.tar.gz: 7f00210ced14e5963220980fd749d0c8765d7555deab200c508daa44ca0770c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebc49df8d9f33381b3134b4dec5b5765abb06bb69b353f21ce695e9f0c4869f9ef36ad4005d6a716d2f73bebfe986158cfc237dd477f6247594a57337adb7bef
|
7
|
+
data.tar.gz: adc08a3fd5b9c6a2dde6daf9e75433c29fc7faf6c6832cd90e1fb8cf7f2be8a3df1e054486c13c22e8d5be1d4e3df74f4a42e27453d145b84a086e17f30efae4
|
data/.travis.yml
CHANGED
@@ -1,63 +1,61 @@
|
|
1
1
|
language: ruby
|
2
2
|
sudo: false
|
3
3
|
jdk:
|
4
|
-
|
5
|
-
- oraclejdk7
|
4
|
+
- openjdk7
|
6
5
|
- oraclejdk8
|
7
6
|
rvm:
|
8
|
-
- jruby-1.7.
|
9
|
-
#- 2.1.2
|
7
|
+
- jruby-1.7.25
|
10
8
|
before_install:
|
11
|
-
|
9
|
+
- unset _JAVA_OPTIONS
|
10
|
+
- export AR_JDBC_VERSION="~> 1.3.24" # due the 50.0 release mess -> not specifying AR ~> 5.0
|
12
11
|
before_script:
|
13
|
-
#- echo \"JRUBY_OPTS: $JRUBY_OPTS\"
|
14
|
-
- export JRUBY_OPTS="$JRUBY_OPTS --server -Xcext.enabled=false -Xcompile.invokedynamic=false"
|
15
12
|
- export JAVA_OPTS="$JAVA_OPTS" # -Xmx600M
|
13
|
+
- 'echo "JAVA_OPTS: $JAVA_OPTS"'
|
14
|
+
- export JRUBY_OPTS="--server -Xcompile.invokedynamic=false"
|
15
|
+
- 'echo "JRUBY_OPTS: $JRUBY_OPTS"'
|
16
16
|
script:
|
17
|
-
-
|
18
|
-
-
|
19
|
-
-
|
20
|
-
- bundle exec rake dbcp:download
|
21
|
-
- bundle exec rake db:create:mysql db:create:postgresql
|
17
|
+
- jruby -rbundler/setup -S rake tomcat:jndi:download tomcat:jdbc:download tomcat:dbcp:download
|
18
|
+
- jruby -rbundler/setup -S rake c3p0:download hikari:download dbcp:download
|
19
|
+
- jruby -rbundler/setup -S rake db:create:mysql db:create:postgresql
|
22
20
|
env:
|
23
|
-
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.
|
24
|
-
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 4.1.
|
25
|
-
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.
|
21
|
+
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.13" HIKARI_VERSION="2.3.12"
|
22
|
+
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 4.1.13" HIKARI_VERSION="2.3.2-java6"
|
23
|
+
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.13" HIKARI_VERSION="2.0.1-java6"
|
26
24
|
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 3.2.18" HIKARI_VERSION="1.4.0"
|
27
|
-
- JRUBY_OPTS="
|
25
|
+
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.2.8" HIKARI_VERSION="2.2.5-java6"
|
28
26
|
matrix:
|
29
27
|
#allow_failures:
|
30
28
|
#- rvm: jruby-head
|
31
29
|
exclude:
|
32
|
-
- rvm: jruby-1.
|
33
|
-
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="
|
34
|
-
jdk:
|
35
|
-
- rvm: jruby-1.
|
36
|
-
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="
|
30
|
+
- rvm: jruby-9.1.16.0
|
31
|
+
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="4.2.8" HIKARI_VERSION="2.3.12"
|
32
|
+
jdk: openjdk7
|
33
|
+
- rvm: jruby-9.1.16.0
|
34
|
+
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="4.2.8" HIKARI_VERSION="2.3.2-java6"
|
37
35
|
jdk: oraclejdk8
|
38
|
-
- rvm: jruby-1.7.
|
39
|
-
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.
|
36
|
+
- rvm: jruby-1.7.25
|
37
|
+
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.16" HIKARI_VERSION="2.0.1-java6"
|
40
38
|
jdk: oraclejdk8
|
41
|
-
- rvm: jruby-1.7.
|
39
|
+
- rvm: jruby-1.7.25
|
42
40
|
env: JRUBY_OPTS="--1.8 $JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 3.2.18" HIKARI_VERSION="2.2.5-java6"
|
43
41
|
jdk: oraclejdk8
|
44
42
|
include:
|
45
43
|
- rvm: jruby-9.0.5.0
|
46
44
|
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.13" HIKARI_VERSION="2.2.5-java6"
|
47
|
-
jdk:
|
48
|
-
- rvm: jruby-9.1.
|
45
|
+
jdk: openjdk7
|
46
|
+
- rvm: jruby-9.1.8.0
|
49
47
|
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 3.2.18" HIKARI_VERSION="2.3.9"
|
50
48
|
jdk: oraclejdk8
|
51
49
|
# AR 4.2
|
52
|
-
- rvm: jruby-1.7.
|
50
|
+
- rvm: jruby-1.7.27
|
53
51
|
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.13" HIKARI_VERSION="2.2.5-java6"
|
54
|
-
jdk:
|
55
|
-
- rvm: jruby-9.1.
|
56
|
-
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.2.
|
52
|
+
jdk: openjdk7
|
53
|
+
- rvm: jruby-9.1.16.0
|
54
|
+
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.2.8" HIKARI_VERSION="2.3.12"
|
57
55
|
jdk: oraclejdk8
|
58
|
-
- rvm: jruby-1.
|
59
|
-
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 4.2.
|
56
|
+
- rvm: jruby-9.1.16.0
|
57
|
+
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 4.2.8" HIKARI_VERSION="2.2.5-java6"
|
60
58
|
jdk: oraclejdk8
|
61
|
-
- rvm: jruby-9.
|
59
|
+
- rvm: jruby-9.1.16.0
|
62
60
|
env: JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 4.1.13" HIKARI_VERSION="2.3.12"
|
63
|
-
jdk:
|
61
|
+
jdk: openjdk7
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -43,7 +43,7 @@ end
|
|
43
43
|
|
44
44
|
pools are expected to work with older ActiveRecord versions, if not let us know.
|
45
45
|
|
46
|
-
### Default Pool
|
46
|
+
### [Default Pool][2]
|
47
47
|
|
48
48
|
Meant as a back-port for users stuck with old Rails versions (< 4.0) on production,
|
49
49
|
facing potential (pool related) concurrency bugs e.g. with high-loads under JRuby.
|
@@ -52,7 +52,7 @@ Based on pool code from 4.x (which works much better than any previous version),
|
|
52
52
|
with a few minor tunings and extensions such as `pool_initial: 0.5` which allows
|
53
53
|
to specify how many connections to initialize in advance when the pool is created.
|
54
54
|
|
55
|
-
### False Pool
|
55
|
+
### [False Pool][3]
|
56
56
|
|
57
57
|
The false pool won't do any actual pooling, it is assumed that an underlying pool
|
58
58
|
is configured. Still, it does maintain a hash of AR connections mapped to threads.
|
@@ -82,7 +82,7 @@ default Tomcat JDBC pool) :
|
|
82
82
|
maxWait: <%= (( ENV['POOL_TIMEOUT'] || 5.0 ).to_f * 1000).to_i %> # default 30s
|
83
83
|
```
|
84
84
|
|
85
|
-
ActiveRecord-JDBC adapter allows you to lookup connection from JNDI using the
|
85
|
+
[ActiveRecord-JDBC][5] adapter allows you to lookup connection from JNDI using the
|
86
86
|
following configuration :
|
87
87
|
|
88
88
|
```
|
@@ -117,7 +117,11 @@ Only tested with ActiveRecord-JDBC-Adapter using the official Postgres' driver.
|
|
117
117
|
|
118
118
|
## Copyright
|
119
119
|
|
120
|
-
Copyright (c)
|
120
|
+
Copyright (c) 2017 [Karol Bucek](http://kares.org).
|
121
121
|
See LICENSE (http://en.wikipedia.org/wiki/MIT_License) for details.
|
122
122
|
|
123
|
-
[0]: http://res.cloudinary.com/kares/image/upload/c_scale,h_600,w_800/v1406451696/bogacs.jpg
|
123
|
+
[0]: http://res.cloudinary.com/kares/image/upload/c_scale,h_600,w_800/v1406451696/bogacs.jpg
|
124
|
+
[1]: http://www.rubydoc.info/gems/activerecord-bogacs/
|
125
|
+
[2]: http://www.rubydoc.info/gems/activerecord-bogacs/ActiveRecord/Bogacs/DefaultPool
|
126
|
+
[3]: http://www.rubydoc.info/gems/activerecord-bogacs/ActiveRecord/Bogacs/FalsePool
|
127
|
+
[5]: https://github.com/jruby/activerecord-jdbc-adapter
|
data/lib/active_record/bogacs.rb
CHANGED
@@ -1,57 +1,6 @@
|
|
1
|
-
require 'active_record/bogacs/version'
|
2
|
-
|
3
1
|
require 'active_record'
|
4
|
-
require 'active_record/version'
|
5
|
-
require 'active_record/connection_adapters/abstract/connection_pool'
|
6
|
-
|
7
|
-
module ActiveRecord
|
8
|
-
module Bogacs
|
9
|
-
autoload :DefaultPool, 'active_record/bogacs/default_pool'
|
10
|
-
autoload :FalsePool, 'active_record/bogacs/false_pool'
|
11
|
-
autoload :ShareablePool, 'active_record/bogacs/shareable_pool'
|
12
|
-
autoload :Reaper, 'active_record/bogacs/reaper'
|
13
|
-
autoload :Validator, 'active_record/bogacs/validator'
|
14
|
-
end
|
15
|
-
autoload :SharedConnection, 'active_record/shared_connection'
|
16
|
-
end
|
17
|
-
|
18
|
-
# NOTE: needs explicit configuration - before connection gets established e.g.
|
19
|
-
#
|
20
|
-
# klass = ActiveRecord::Bogacs::FalsePool
|
21
|
-
# ActiveRecord::ConnectionAdapters::ConnectionHandler.connection_pool_class = klass
|
22
|
-
#
|
23
|
-
module ActiveRecord
|
24
|
-
module ConnectionAdapters
|
25
|
-
# @private there's no other way to change the pool class to use but to patch :(
|
26
|
-
ConnectionHandler.class_eval do
|
27
|
-
|
28
|
-
@@connection_pool_class = ConnectionAdapters::ConnectionPool
|
29
|
-
|
30
|
-
def connection_pool_class; @@connection_pool_class end
|
31
|
-
def self.connection_pool_class=(klass); @@connection_pool_class = klass end
|
32
|
-
|
33
|
-
if ActiveRecord::VERSION::MAJOR > 3 # 4.x
|
34
2
|
|
35
|
-
|
36
|
-
|
37
|
-
owner_to_pool[owner.name] = connection_pool_class.new(spec)
|
38
|
-
end
|
39
|
-
|
40
|
-
elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 2
|
41
|
-
|
42
|
-
def establish_connection(name, spec)
|
43
|
-
@class_to_pool[name] =
|
44
|
-
( @connection_pools[spec] ||= connection_pool_class.new(spec) )
|
45
|
-
end
|
46
|
-
|
47
|
-
else # 2.3/3.0/3.1
|
48
|
-
|
49
|
-
def establish_connection(name, spec)
|
50
|
-
@connection_pools[name] = connection_pool_class.new(spec)
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
3
|
+
require 'active_record/bogacs/version'
|
4
|
+
require 'active_record/bogacs/autoload'
|
54
5
|
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
6
|
+
require 'active_record/connection_adapters/pool_class.rb'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Bogacs
|
3
|
+
autoload :DefaultPool, 'active_record/bogacs/default_pool'
|
4
|
+
autoload :FalsePool, 'active_record/bogacs/false_pool'
|
5
|
+
autoload :ShareablePool, 'active_record/bogacs/shareable_pool'
|
6
|
+
autoload :Reaper, 'active_record/bogacs/reaper'
|
7
|
+
autoload :Validator, 'active_record/bogacs/validator'
|
8
|
+
end
|
9
|
+
autoload :SharedConnection, 'active_record/shared_connection'
|
10
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'monitor'
|
3
3
|
|
4
|
+
require 'active_record/version'
|
5
|
+
|
4
6
|
require 'active_record/connection_adapters/adapter_compat'
|
5
7
|
require 'active_record/bogacs/pool_support'
|
6
8
|
require 'active_record/bogacs/thread_safe'
|
@@ -8,41 +10,13 @@ require 'active_record/bogacs/thread_safe'
|
|
8
10
|
module ActiveRecord
|
9
11
|
module Bogacs
|
10
12
|
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# Connections can be obtained and used from a connection pool in several
|
14
|
-
# ways:
|
15
|
-
#
|
16
|
-
# 1. Simply use ActiveRecord::Base.connection as with Active Record 2.1 and
|
17
|
-
# earlier (pre-connection-pooling). Eventually, when you're done with
|
18
|
-
# the connection(s) and wish it to be returned to the pool, you call
|
19
|
-
# ActiveRecord::Base.clear_active_connections!.
|
20
|
-
# 2. Manually check out a connection from the pool with
|
21
|
-
# ActiveRecord::Base.connection_pool.checkout. You are responsible for
|
22
|
-
# returning this connection to the pool when finished by calling
|
23
|
-
# ActiveRecord::Base.connection_pool.checkin(connection).
|
24
|
-
# 3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which
|
25
|
-
# obtains a connection, yields it as the sole argument to the block,
|
26
|
-
# and returns it to the pool after the block completes.
|
13
|
+
# A "default" `ActiveRecord::ConnectionAdapters::ConnectionPool`-like pool
|
14
|
+
# implementation with compatibility across (older) Rails versions.
|
27
15
|
#
|
28
|
-
#
|
29
|
-
# compatible with AbstractAdapter's interface).
|
16
|
+
# Currently, mostly, based on ActiveRecord **4.2**.
|
30
17
|
#
|
31
|
-
#
|
18
|
+
# http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html
|
32
19
|
#
|
33
|
-
# There are several connection-pooling-related options that you can add to
|
34
|
-
# your database connection configuration:
|
35
|
-
#
|
36
|
-
# * **pool**: number indicating size of connection pool (default 5)
|
37
|
-
# * **checkout_timeout**: number of seconds to block and wait for a connection
|
38
|
-
# before giving up and raising a timeout error (default 5 seconds).
|
39
|
-
# * **pool_initial**: number of connections to pre-initialize when the pool
|
40
|
-
# is created (default 0).
|
41
|
-
# * **reaping_frequency**: frequency in seconds to periodically run a reaper,
|
42
|
-
# which attempts to find and close "dead" connections (can occur if a caller
|
43
|
-
# forgets to close a connection at the end of a thread or a thread dies unexpectedly)
|
44
|
-
# Default is `nil`, which means don't run the periodical Reaper at all (reaping
|
45
|
-
# will still happen occasionally).
|
46
20
|
class DefaultPool
|
47
21
|
# Threadsafe, fair, FIFO queue. Meant to be used by ConnectionPool
|
48
22
|
# with which it shares a Monitor. But could be a generic Queue.
|
@@ -106,9 +80,8 @@ module ActiveRecord
|
|
106
80
|
# available, waiting up to +timeout+ seconds for an element to
|
107
81
|
# become available.
|
108
82
|
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
# becomes available after +timeout+ seconds,
|
83
|
+
# @raise [ActiveRecord::ConnectionTimeoutError] if +timeout+ given and no element
|
84
|
+
# becomes available after +timeout+ seconds
|
112
85
|
def poll(timeout = nil, &block)
|
113
86
|
synchronize do
|
114
87
|
if timeout
|
@@ -186,12 +159,28 @@ module ActiveRecord
|
|
186
159
|
attr_reader :spec, :connections, :size, :reaper, :validator
|
187
160
|
attr_reader :initial_size
|
188
161
|
|
189
|
-
# Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
|
162
|
+
# Creates a new `ConnectionPool` object. +spec+ is a ConnectionSpecification
|
190
163
|
# object which describes database connection information (e.g. adapter,
|
191
164
|
# host name, username, password, etc), as well as the maximum size for
|
192
165
|
# this ConnectionPool.
|
193
166
|
#
|
194
|
-
# The default ConnectionPool maximum size is 5
|
167
|
+
# @note The default ConnectionPool maximum size is **5**.
|
168
|
+
#
|
169
|
+
# @param [Hash] spec a `ConnectionSpecification`
|
170
|
+
#
|
171
|
+
# @option spec.config [Integer] :pool number indicating size of connection pool (default 5)
|
172
|
+
# @option spec.config [Float] :checkout_timeout number of seconds to block and
|
173
|
+
# wait for a connection before giving up raising a timeout (default 5 seconds).
|
174
|
+
# @option spec.config [Integer] :pool_initial number of connections to pre-initialize
|
175
|
+
# when the pool is created (default 0).
|
176
|
+
# @option spec.config [Float] :reaping_frequency frequency in seconds to periodically
|
177
|
+
# run a reaper, which attempts to find and close "dead" connections (can occur
|
178
|
+
# if a caller forgets to close a connection at the end of a thread or a thread
|
179
|
+
# dies unexpectedly) default is `nil` - don't run the periodical Reaper (reaping
|
180
|
+
# will still happen occasionally).
|
181
|
+
# @option spec.config [Float] :validate_frequency frequency in seconds to periodically
|
182
|
+
# run a connection validation (in a separate thread), to avoid potentially stale
|
183
|
+
# sockets when connections stay open (pooled but unused) for longer periods.
|
195
184
|
def initialize(spec)
|
196
185
|
super()
|
197
186
|
|
@@ -230,7 +219,7 @@ module ActiveRecord
|
|
230
219
|
require 'active_record/bogacs/validator' unless self.class.const_defined?(:Validator)
|
231
220
|
@validator = Validator.new self, frequency, spec.config[:validate_timeout]
|
232
221
|
if @validator.run && @reaping
|
233
|
-
logger && logger.
|
222
|
+
logger && logger.warn(":validate_frequency configured alongside with :reaping_frequency")
|
234
223
|
end
|
235
224
|
end
|
236
225
|
end
|
@@ -372,7 +361,7 @@ module ActiveRecord
|
|
372
361
|
|
373
362
|
# Check-in a database connection back into the pool.
|
374
363
|
#
|
375
|
-
# @param [ActiveRecord::ConnectionAdapters::AbstractAdapter] connection
|
364
|
+
# @param conn [ActiveRecord::ConnectionAdapters::AbstractAdapter] connection
|
376
365
|
# object, which was obtained earlier by calling #checkout on this pool
|
377
366
|
# @see #checkout
|
378
367
|
def checkin(conn, released = nil)
|
@@ -440,8 +429,8 @@ module ActiveRecord
|
|
440
429
|
# connection if the pool is not at capacity, 3) waiting on the
|
441
430
|
# queue for a connection to become available.
|
442
431
|
#
|
443
|
-
#
|
444
|
-
#
|
432
|
+
# @raise [ActiveRecord::ConnectionTimeoutError]
|
433
|
+
# @raise [ActiveRecord::ConnectionNotEstablished]
|
445
434
|
def acquire_connection
|
446
435
|
if conn = @available.poll
|
447
436
|
conn
|
@@ -488,4 +477,4 @@ module ActiveRecord
|
|
488
477
|
end
|
489
478
|
|
490
479
|
end
|
491
|
-
end
|
480
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_record/version'
|
2
|
+
|
1
3
|
require 'active_record/bogacs/pool_support'
|
2
4
|
require 'active_record/bogacs/thread_safe'
|
3
5
|
|
@@ -126,17 +128,8 @@ module ActiveRecord
|
|
126
128
|
# Check-out a database connection from the pool, indicating that you want
|
127
129
|
# to use it. You should call #checkin when you no longer need this.
|
128
130
|
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
# If all connections are leased and the pool is at capacity (meaning the
|
133
|
-
# number of currently leased connections is greater than or equal to the
|
134
|
-
# size limit set), an ActiveRecord::ConnectionTimeoutError exception will be raised.
|
135
|
-
#
|
136
|
-
# Returns: an AbstractAdapter object.
|
137
|
-
#
|
138
|
-
# Raises:
|
139
|
-
# - ConnectionTimeoutError: no connection can be obtained from the pool.
|
131
|
+
# @return [ActiveRecord::ConnectionAdapters::AbstractAdapter]
|
132
|
+
# @raise [ActiveRecord::ConnectionTimeoutError] no connection can be obtained from the pool
|
140
133
|
def checkout
|
141
134
|
#synchronize do
|
142
135
|
conn = checkout_new_connection # acquire_connection
|
@@ -149,8 +142,9 @@ module ActiveRecord
|
|
149
142
|
# Check-in a database connection back into the pool, indicating that you
|
150
143
|
# no longer need this connection.
|
151
144
|
#
|
152
|
-
#
|
153
|
-
# calling
|
145
|
+
# @param conn [ActiveRecord::ConnectionAdapters::AbstractAdapter] connection
|
146
|
+
# object, which was obtained earlier by calling #checkout on this pool
|
147
|
+
# @see #checkout
|
154
148
|
def checkin(conn, do_release = true)
|
155
149
|
release(conn) if do_release
|
156
150
|
#synchronize do
|
@@ -173,13 +167,7 @@ module ActiveRecord
|
|
173
167
|
|
174
168
|
private
|
175
169
|
|
176
|
-
#
|
177
|
-
# from the queue of available connections, 2) creating a new
|
178
|
-
# connection if the pool is not at capacity, 3) waiting on the
|
179
|
-
# queue for a connection to become available.
|
180
|
-
#
|
181
|
-
# Raises:
|
182
|
-
# - ConnectionTimeoutError if a connection could not be acquired
|
170
|
+
# @raise [ActiveRecord::ConnectionTimeoutError]
|
183
171
|
def acquire_connection
|
184
172
|
# underlying pool will poll and block if "empty" (all checked-out)
|
185
173
|
#if conn = @available.poll
|
@@ -3,22 +3,20 @@ require 'thread'
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Bogacs
|
5
5
|
|
6
|
-
# Every
|
6
|
+
# Every *frequency* seconds, the reaper will "reap" a pool it belongs to.
|
7
7
|
# Reaping means detecting stale cached connections in the pool - those that
|
8
8
|
# were checked-out by a thread but never checked back in after the thread
|
9
9
|
# finished/died.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
# Instead the thread will be restarted and reaping continues at the next tick.
|
13
|
-
#
|
14
|
-
# Configure the frequency by setting `:reaping_frequency` in your database yaml file.
|
11
|
+
# Configure the frequency by setting `:reaping_frequency` in your database.yml.
|
15
12
|
#
|
13
|
+
# @note This version is fail safe - raised errors won't stop the reaping process.
|
16
14
|
class Reaper
|
17
15
|
|
18
16
|
attr_reader :pool, :frequency
|
19
17
|
attr_accessor :retry_error
|
20
18
|
|
21
|
-
# Reaper.new(
|
19
|
+
# `Reaper.new(pool, spec.config[:reaping_frequency]).run`
|
22
20
|
# @private
|
23
21
|
def initialize(pool, frequency)
|
24
22
|
@pool = pool;
|
@@ -1,9 +1,9 @@
|
|
1
|
+
require 'active_record/version'
|
1
2
|
require 'active_record/connection_adapters/abstract/connection_pool'
|
2
3
|
|
3
4
|
require 'thread'
|
4
5
|
|
5
6
|
require 'active_record/bogacs/thread_safe'
|
6
|
-
|
7
7
|
require 'active_record/bogacs/pool_support'
|
8
8
|
|
9
9
|
# NOTE: needs explicit configuration - before connection gets established e.g.
|
@@ -12,13 +12,9 @@ require 'active_record/bogacs/thread_safe'
|
|
12
12
|
module ActiveRecord
|
13
13
|
module Bogacs
|
14
14
|
|
15
|
-
# Every
|
15
|
+
# Every *frequency* seconds, the _validator_ will perform connection validation
|
16
16
|
# on a pool it operates.
|
17
17
|
#
|
18
|
-
# @note Do not use a reaper with the validator as reaping (stale connection detection
|
19
|
-
# and removal) is part of the validation process and will only likely slow things down
|
20
|
-
# as all pool connection updates needs to be synchronized.
|
21
|
-
#
|
22
18
|
# Configure the frequency by setting `:validate_frequency` in your AR configuration.
|
23
19
|
#
|
24
20
|
# We recommend not setting values too low as that would drain the pool's performance
|
@@ -26,11 +22,15 @@ module ActiveRecord
|
|
26
22
|
# checkout - the validator is intended to detect long idle pooled connections "ahead
|
27
23
|
# of time" instead of upon retrieval.
|
28
24
|
#
|
25
|
+
# @note Do not use a reaper with the validator!
|
26
|
+
# Reaping (stale connection detection and removal) is part of the validation
|
27
|
+
# process and will only slow things down as all pool connection updates needs
|
28
|
+
# to be synchronized.
|
29
29
|
class Validator
|
30
30
|
|
31
31
|
attr_reader :pool, :frequency, :timeout
|
32
32
|
|
33
|
-
# Validator.new(
|
33
|
+
# `Validator.new(pool, spec.config[:validate_frequency]).run`
|
34
34
|
# @private
|
35
35
|
def initialize(pool, frequency = 60, timeout = nil)
|
36
36
|
@pool = pool; PoolAdaptor.adapt! pool
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_record/version'
|
3
|
+
require 'active_record/connection_adapters/abstract/connection_pool'
|
4
|
+
|
5
|
+
# NOTE: needs explicit configuration - before connection gets established e.g.
|
6
|
+
#
|
7
|
+
# klass = ActiveRecord::Bogacs::FalsePool
|
8
|
+
# ActiveRecord::ConnectionAdapters::ConnectionHandler.connection_pool_class = klass
|
9
|
+
#
|
10
|
+
module ActiveRecord
|
11
|
+
module ConnectionAdapters
|
12
|
+
# @private there's no other way to change the pool class to use but to patch :(
|
13
|
+
ConnectionHandler.class_eval do
|
14
|
+
|
15
|
+
@@connection_pool_class = ConnectionAdapters::ConnectionPool
|
16
|
+
|
17
|
+
def connection_pool_class; @@connection_pool_class end
|
18
|
+
def self.connection_pool_class=(klass); @@connection_pool_class = klass end
|
19
|
+
|
20
|
+
if ActiveRecord::VERSION::MAJOR > 3 # 4.x
|
21
|
+
|
22
|
+
def establish_connection(owner, spec)
|
23
|
+
@class_to_pool.clear
|
24
|
+
owner_to_pool[owner.name] = connection_pool_class.new(spec)
|
25
|
+
end
|
26
|
+
|
27
|
+
elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 2
|
28
|
+
|
29
|
+
def establish_connection(name, spec)
|
30
|
+
@class_to_pool[name] =
|
31
|
+
( @connection_pools[spec] ||= connection_pool_class.new(spec) )
|
32
|
+
end
|
33
|
+
|
34
|
+
else # 2.3/3.0/3.1
|
35
|
+
|
36
|
+
def establish_connection(name, spec)
|
37
|
+
@connection_pools[name] = connection_pool_class.new(spec)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -52,6 +52,8 @@ prepared_statements = ENV['AR_PREPARED_STATEMENTS'] # || true
|
|
52
52
|
config[:'prepared_statements'] = prepared_statements if prepared_statements
|
53
53
|
#jdbc_properties = { 'logUnclosedConnections' => true, 'loginTimeout' => 5 }
|
54
54
|
#config[:'properties'] = jdbc_properties
|
55
|
+
config[:'properties'] ||= {}
|
56
|
+
config[:'properties']['useSSL'] ||= 'false' if config[:adapter].starts_with?('mysql')
|
55
57
|
|
56
58
|
checkout_timeout = ENV['AR_POOL_CHECKOUT_TIMEOUT'] || checkout_timeout
|
57
59
|
config[:'checkout_timeout'] = checkout_timeout.to_f if checkout_timeout
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-bogacs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karol Bucek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- Rakefile
|
68
68
|
- activerecord-bogacs.gemspec
|
69
69
|
- lib/active_record/bogacs.rb
|
70
|
+
- lib/active_record/bogacs/autoload.rb
|
70
71
|
- lib/active_record/bogacs/default_pool.rb
|
71
72
|
- lib/active_record/bogacs/false_pool.rb
|
72
73
|
- lib/active_record/bogacs/pool_support.rb
|
@@ -77,6 +78,7 @@ files:
|
|
77
78
|
- lib/active_record/bogacs/validator.rb
|
78
79
|
- lib/active_record/bogacs/version.rb
|
79
80
|
- lib/active_record/connection_adapters/adapter_compat.rb
|
81
|
+
- lib/active_record/connection_adapters/pool_class.rb
|
80
82
|
- lib/active_record/shared_connection.rb
|
81
83
|
- test/active_record/bogacs/default_pool_test.rb
|
82
84
|
- test/active_record/bogacs/false_pool_test.rb
|
@@ -108,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
110
|
version: '0'
|
109
111
|
requirements: []
|
110
112
|
rubyforge_project:
|
111
|
-
rubygems_version: 2.
|
113
|
+
rubygems_version: 2.6.13
|
112
114
|
signing_key:
|
113
115
|
specification_version: 4
|
114
116
|
summary: 'Bogacs contains several pool implementations that can be used as a replacement
|