activerecord-bogacs 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +6 -6
- data/Gemfile +15 -1
- data/README.md +9 -10
- data/Rakefile +97 -24
- data/lib/active_record/bogacs/false_pool.rb +23 -20
- data/lib/active_record/bogacs/pool_support.rb +21 -1
- data/lib/active_record/bogacs/shareable_pool.rb +31 -11
- data/lib/active_record/bogacs/version.rb +1 -1
- data/lib/active_record/connection_adapters/adapter_compat.rb +17 -15
- data/test/active_record/bogacs/false_pool_test.rb +140 -30
- data/test/active_record/bogacs/shareable_pool/connection_sharing_test.rb +3 -2
- data/test/active_record/builtin_pool_test.rb +2 -1
- data/test/active_record/connection_pool_test_methods.rb +5 -1
- data/test/test_helper.rb +130 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cade13cd15b5374a780d1f8d0de1d63b7e0c89a
|
4
|
+
data.tar.gz: 51949daaccd651b2d8fa51ccfa3379109885ed16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91259b8c14a9eeea273eddb83c0b561ab65908683619a6b4f0bd7d744198c7a9e1a1b4dae5d1705b82b98fa5e8c0097d00b06c9b1c90ca7113cbfa1b59018fa7
|
7
|
+
data.tar.gz: 9f814b2b2eb6ced23c2da439c2dfd05c9fec270ed50f2f410748c75906e9911f62a7e794b28e5021de0de9eec5169b13d381dd077fba94fe1f39b159b6bebfde
|
data/.travis.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
language: ruby
|
2
2
|
jdk:
|
3
|
-
|
3
|
+
#- openjdk6
|
4
4
|
- oraclejdk7
|
5
5
|
- oraclejdk8
|
6
6
|
rvm:
|
@@ -8,19 +8,19 @@ rvm:
|
|
8
8
|
#- jruby-head
|
9
9
|
#- jruby-18mode
|
10
10
|
#- jruby-19mode
|
11
|
-
#- 2.1.
|
11
|
+
#- 2.1.2
|
12
12
|
before_install:
|
13
13
|
- ((jruby -v | grep 1.8.7) && jruby --1.9 -S gem update --system 2.1.11) || true
|
14
14
|
before_script:
|
15
|
-
|
15
|
+
#- echo \"JRUBY_OPTS: $JRUBY_OPTS\"
|
16
16
|
- export JRUBY_OPTS="--server -Xcext.enabled=false -Xcompile.invokedynamic=false"
|
17
17
|
- export JAVA_OPTS="$JAVA_OPTS" # -Xmx600M
|
18
|
-
- echo "JAVA_OPTS: $JAVA_OPTS"
|
19
18
|
script:
|
20
19
|
- bundle exec rake tomcat:jndi:download tomcat:jdbc:download tomcat:dbcp:download
|
20
|
+
- bundle exec rake c3p0:download hikari:download
|
21
21
|
- bundle exec rake db:create:mysql db:create:postgresql
|
22
22
|
env:
|
23
|
-
- JRUBY_OPTS="
|
23
|
+
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 4.1.6"
|
24
|
+
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 4.1.6"
|
24
25
|
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql AR_VERSION="~> 3.2.18"
|
25
26
|
- JRUBY_OPTS="--1.8 $JRUBY_OPTS" AR_ADAPTER=mysql AR_VERSION="~> 3.2.18"
|
26
|
-
- JRUBY_OPTS="$JRUBY_OPTS" AR_ADAPTER=postgresql
|
data/Gemfile
CHANGED
@@ -16,7 +16,21 @@ else
|
|
16
16
|
gem 'activerecord', :require => nil
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
platform :jruby do
|
20
|
+
if version = ENV['AR_JDBC_VERSION']
|
21
|
+
if version.index('/') && ::File.exist?(version)
|
22
|
+
gem 'activerecord-jdbc-adapter', :path => version
|
23
|
+
elsif version =~ /^[0-9abcdef]+$/
|
24
|
+
gem 'activerecord-jdbc-adapter', :github => 'jruby/activerecord-jdbc-adapter', :ref => version
|
25
|
+
elsif version.index('.').nil?
|
26
|
+
gem 'activerecord-jdbc-adapter', :github => 'jruby/activerecord-jdbc-adapter', :branch => version
|
27
|
+
else
|
28
|
+
gem 'activerecord-jdbc-adapter', version, :require => nil
|
29
|
+
end
|
30
|
+
else
|
31
|
+
gem 'activerecord-jdbc-adapter', :require => nil
|
32
|
+
end
|
33
|
+
end
|
20
34
|
|
21
35
|
#gem 'thread_safe', :require => nil # "optional" - we can roll without it
|
22
36
|
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# ActiveRecord::Bogacs
|
2
2
|
|
3
|
-
ActiveRecord pooling "
|
3
|
+
ActiveRecord (all-year) pooling "alternatives" ... in a relaxed 'spa' fashion.
|
4
4
|
|
5
5
|
![Bogacs][0]
|
6
6
|
|
7
7
|
Bogács is a village in Borsod-Abaúj-Zemplén county, Hungary.
|
8
8
|
|
9
|
-
**WiP:
|
9
|
+
**WiP: do not put this on production if you do not understand the consequences!**
|
10
10
|
|
11
11
|
## Install
|
12
12
|
|
@@ -34,7 +34,7 @@ module MyApp
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
# sample
|
37
|
+
# sample AR-Bogacs setup using the "false" pool :
|
38
38
|
if Rails.env.production?
|
39
39
|
pool_class = ActiveRecord::Bogacs::FalsePool
|
40
40
|
ActiveRecord::ConnectionAdapters::ConnectionHandler.connection_pool_class = pool_class
|
@@ -50,13 +50,13 @@ facing potential (pool related) concurrency bugs e.g. with high-loads under JRub
|
|
50
50
|
|
51
51
|
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
|
-
to specify how many connections to
|
53
|
+
to specify how many connections to initialize in advance when the pool is created.
|
54
54
|
|
55
55
|
### False Pool
|
56
56
|
|
57
|
-
The false pool won't do any actual pooling, it is
|
58
|
-
is configured.
|
59
|
-
Ignores
|
57
|
+
The false pool won't do any actual pooling, it is assumed that an underlying pool
|
58
|
+
is configured. Still, it does maintain a hash of AR connections mapped to threads.
|
59
|
+
Ignores pool related configurations such as `pool: 42` or `checkout_timeout: 2.5`.
|
60
60
|
|
61
61
|
**NOTE:** be sure to configure an underlying pool e.g. with Trinidad (using the
|
62
62
|
default Tomcat JDBC pool) :
|
@@ -74,7 +74,7 @@ default Tomcat JDBC pool) :
|
|
74
74
|
initialSize: <%= ENV['POOL_INITIAL'] || 25 %> # connections created on start
|
75
75
|
maxActive: <%= ENV['POOL_SIZE'] || 100 %> # default 100 (AR pool: size)
|
76
76
|
maxIdle: <%= ENV['POOL_SIZE'] || 100 %> # max connections kept in the pool
|
77
|
-
minIdle: <%= ENV['
|
77
|
+
minIdle: <%= ENV['POOL_INITIAL'] || 50 %>
|
78
78
|
# idle connections are checked periodically (if enabled) and connections
|
79
79
|
# that been idle for longer than minEvictableIdleTimeMillis will be released
|
80
80
|
minEvictableIdleTimeMillis: <%= 3 * 60 * 1000 %> # default 60s
|
@@ -91,8 +91,7 @@ production:
|
|
91
91
|
jndi: java:/comp/env/jdbc/BogacsDB
|
92
92
|
```
|
93
93
|
|
94
|
-
**NOTE:** using
|
95
|
-
that is `no_pool: 5` or `checkout_timeout: 5` defaults!
|
94
|
+
**NOTE:** when using `FalsePool` there's nothing to configure (in *database.yml*)!
|
96
95
|
|
97
96
|
### Shareable Pool
|
98
97
|
|
data/Rakefile
CHANGED
@@ -10,8 +10,8 @@ task :default => :test
|
|
10
10
|
desc "Creates a (test) MySQL database"
|
11
11
|
task 'db:create:mysql' do
|
12
12
|
fail "could not create database: mysql executable not found" unless mysql = _which('mysql')
|
13
|
-
ENV['Rake'] = true; ENV['AR_ADAPTER'] ||= 'mysql'
|
14
|
-
|
13
|
+
ENV['Rake'] = true.to_s; ENV['AR_ADAPTER'] ||= 'mysql'
|
14
|
+
require File.expand_path('test/test_helper.rb', File.dirname(__FILE__))
|
15
15
|
|
16
16
|
script = "DROP DATABASE IF EXISTS `#{AR_CONFIG[:database]}`;"
|
17
17
|
script << "CREATE DATABASE `#{AR_CONFIG[:database]}` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_general_ci`;"
|
@@ -20,22 +20,20 @@ task 'db:create:mysql' do
|
|
20
20
|
script << "SET PASSWORD FOR #{AR_CONFIG[:username]}@localhost = PASSWORD('#{AR_CONFIG[:password]}');"
|
21
21
|
end
|
22
22
|
params = { '-u' => 'root' }
|
23
|
-
if ENV['DATABASE_YML']
|
24
|
-
require 'yaml'
|
23
|
+
if ENV['DATABASE_YML']; require 'yaml'
|
25
24
|
password = YAML.load(File.new(ENV['DATABASE_YML']))["production"]["password"]
|
26
25
|
params['--password'] = password
|
27
26
|
end
|
28
27
|
puts "Creating MySQL database: #{AR_CONFIG[:database]}"
|
29
28
|
sh "cat #{_sql_script(script).path} | #{mysql} #{params.to_a.join(' ')}", :verbose => $VERBOSE
|
30
|
-
puts "... run tests with MySQL using: `rake test
|
29
|
+
# puts "... run tests with MySQL using: `AR_ADAPTER=mysql rake test `"
|
31
30
|
end
|
32
31
|
|
33
32
|
desc "Creates a (test) PostgreSQL database"
|
34
33
|
task 'db:create:postgresql' do
|
35
34
|
fail 'could not create database: psql executable not found' unless psql = _which('psql')
|
36
|
-
|
37
|
-
|
38
|
-
load File.expand_path('test/test_helper.rb', File.dirname(__FILE__))
|
35
|
+
ENV['Rake'] = true.to_s; ENV['AR_ADAPTER'] ||= 'postgresql'
|
36
|
+
require File.expand_path('test/test_helper.rb', File.dirname(__FILE__))
|
39
37
|
|
40
38
|
script = "DROP DATABASE IF EXISTS #{AR_CONFIG[:database]};"
|
41
39
|
if pg_user = AR_CONFIG[:username] || ENV['PGUSER'] || ENV_JAVA['user.name']
|
@@ -44,10 +42,15 @@ task 'db:create:postgresql' do
|
|
44
42
|
script << "CREATE USER #{pg_user} CREATEDB SUPERUSER LOGIN PASSWORD '#{pg_password}';"
|
45
43
|
end
|
46
44
|
script << "CREATE DATABASE #{AR_CONFIG[:database]} OWNER #{pg_user || 'postgres'};"
|
47
|
-
|
45
|
+
|
46
|
+
psql_params = "-U #{ENV['PSQL_USER'] || 'postgres'}"
|
47
|
+
psql_params << " -h #{ENV['PGHOST']}" if ENV['PGHOST']
|
48
|
+
psql_params << " -p #{ENV['PGPORT']}" if ENV['PGPORT']
|
49
|
+
psql_params << " -q " unless $VERBOSE
|
50
|
+
|
48
51
|
puts "Creating PostgreSQL database: #{AR_CONFIG[:database]}"
|
49
|
-
sh "cat #{_sql_script(script).path} | #{psql} #{
|
50
|
-
puts "... run tests with PostgreSQL using: `rake test
|
52
|
+
sh "cat #{_sql_script(script).path} | #{psql} #{psql_params}", :verbose => $VERBOSE
|
53
|
+
# puts "... run tests with PostgreSQL using: `AR_ADAPTER=postgresql rake test `"
|
51
54
|
end
|
52
55
|
|
53
56
|
def _sql_script(content, name = '_sql_script')
|
@@ -71,6 +74,22 @@ def _which(cmd)
|
|
71
74
|
nil
|
72
75
|
end
|
73
76
|
|
77
|
+
def _download(uri, download_dir, as_file_name)
|
78
|
+
require 'open-uri'; require 'tmpdir'
|
79
|
+
|
80
|
+
temp_dir = File.join(Dir.tmpdir, (Time.now.to_f * 1000).to_i.to_s)
|
81
|
+
FileUtils.mkdir temp_dir
|
82
|
+
|
83
|
+
Dir.chdir(temp_dir) do
|
84
|
+
FileUtils.mkdir download_dir unless File.exist?(download_dir)
|
85
|
+
puts "downloading #{uri}"
|
86
|
+
file = open(uri)
|
87
|
+
FileUtils.cp file.path, File.join(download_dir, as_file_name)
|
88
|
+
end
|
89
|
+
|
90
|
+
FileUtils.rm_r temp_dir
|
91
|
+
end
|
92
|
+
|
74
93
|
namespace :tomcat do
|
75
94
|
|
76
95
|
tomcat_maven_repo = 'http://repo2.maven.org/maven2/org/apache/tomcat'
|
@@ -87,19 +106,7 @@ namespace :tomcat do
|
|
87
106
|
|
88
107
|
uri = "#{tomcat_maven_repo}/#{tomcat_pool}/#{version}/#{tomcat_pool}-#{version}.jar"
|
89
108
|
|
90
|
-
|
91
|
-
|
92
|
-
temp_dir = File.join(Dir.tmpdir, (Time.now.to_f * 1000).to_i.to_s)
|
93
|
-
FileUtils.mkdir temp_dir
|
94
|
-
|
95
|
-
Dir.chdir(temp_dir) do
|
96
|
-
FileUtils.mkdir download_dir unless File.exist?(download_dir)
|
97
|
-
puts "downloading #{uri}"
|
98
|
-
file = open(uri)
|
99
|
-
FileUtils.cp file.path, File.join(download_dir, tomcat_pool_jar)
|
100
|
-
end
|
101
|
-
|
102
|
-
FileUtils.rm_r temp_dir
|
109
|
+
_download(uri, download_dir, tomcat_pool_jar)
|
103
110
|
end
|
104
111
|
|
105
112
|
task :check do
|
@@ -165,3 +172,69 @@ namespace :tomcat do
|
|
165
172
|
end
|
166
173
|
|
167
174
|
end
|
175
|
+
|
176
|
+
namespace :c3p0 do
|
177
|
+
|
178
|
+
mchange_base_repo = 'http://repo2.maven.org/maven2/com/mchange'
|
179
|
+
download_dir = File.expand_path('test/jars', File.dirname(__FILE__))
|
180
|
+
c3p0_version = '0.9.5-pre9'
|
181
|
+
mchange_commons_version = '0.2.8'
|
182
|
+
|
183
|
+
c3p0_jar = "c3p0-#{c3p0_version}.jar"
|
184
|
+
mchange_commons_jar = "mchange-commons-java-#{mchange_commons_version}.jar"
|
185
|
+
|
186
|
+
task :download, :version do |_,args| # rake c3p0:download
|
187
|
+
# version = args[:version] || version_default
|
188
|
+
|
189
|
+
uri = "#{mchange_base_repo}/mchange-commons-java/#{mchange_commons_version}/#{mchange_commons_jar}"
|
190
|
+
|
191
|
+
_download(uri, download_dir, mchange_commons_jar)
|
192
|
+
|
193
|
+
uri = "#{mchange_base_repo}/c3p0/#{c3p0_version}/#{c3p0_jar}"
|
194
|
+
|
195
|
+
_download(uri, download_dir, c3p0_jar)
|
196
|
+
end
|
197
|
+
|
198
|
+
task :clear do
|
199
|
+
Dir.glob( File.join(download_dir, '{c3p0,mchange-commons}*.jar') ).each { |jar| rm jar }
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
namespace :hikari do
|
205
|
+
|
206
|
+
hikari_base_repo = 'http://repo2.maven.org/maven2/com/zaxxer'
|
207
|
+
slf4j_base_repo = 'http://repo2.maven.org/maven2/org/slf4j'
|
208
|
+
javassist_base_repo = 'http://repo2.maven.org/maven2/org/javassist'
|
209
|
+
download_dir = File.expand_path('test/jars', File.dirname(__FILE__))
|
210
|
+
hikari_version = '1.3.9'
|
211
|
+
slf4j_version = '1.7.7'
|
212
|
+
javassist_version = '3.18.2-GA'
|
213
|
+
|
214
|
+
slf4j_api_jar = "slf4j-api-#{slf4j_version}.jar"
|
215
|
+
slf4j_simple_jar = "slf4j-simple-#{slf4j_version}.jar"
|
216
|
+
javassist_jar = "javassist-#{javassist_version}.jar"
|
217
|
+
|
218
|
+
task :download, :version do |_,args| # rake c3p0:download
|
219
|
+
version = args[:version] || hikari_version
|
220
|
+
|
221
|
+
hikari_jar = "HikariCP-#{hikari_version}.jar"
|
222
|
+
|
223
|
+
uri = "#{hikari_base_repo}/HikariCP/#{version}/#{hikari_jar}"
|
224
|
+
_download(uri, download_dir, hikari_jar)
|
225
|
+
|
226
|
+
uri = "#{slf4j_base_repo}/slf4j-api/#{slf4j_version}/#{slf4j_api_jar}"
|
227
|
+
_download(uri, download_dir, slf4j_api_jar)
|
228
|
+
|
229
|
+
uri = "#{slf4j_base_repo}/slf4j-simple/#{slf4j_version}/#{slf4j_simple_jar}"
|
230
|
+
_download(uri, download_dir, slf4j_simple_jar)
|
231
|
+
|
232
|
+
uri = "#{javassist_base_repo}/javassist/#{javassist_version}/#{javassist_jar}"
|
233
|
+
_download(uri, download_dir, javassist_jar)
|
234
|
+
end
|
235
|
+
|
236
|
+
task :clear do
|
237
|
+
Dir.glob( File.join(download_dir, '{HikariCP,slf4j}*.jar') ).each { |jar| rm jar }
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
@@ -220,7 +220,7 @@ module ActiveRecord
|
|
220
220
|
rescue ConnectionTimeoutError => e
|
221
221
|
raise e
|
222
222
|
rescue => e
|
223
|
-
raise ConnectionTimeoutError, e.message if
|
223
|
+
raise ConnectionTimeoutError, e.message if timeout_error?(e)
|
224
224
|
raise e
|
225
225
|
end
|
226
226
|
conn.pool = self
|
@@ -233,27 +233,30 @@ module ActiveRecord
|
|
233
233
|
# conn
|
234
234
|
#end
|
235
235
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
236
|
+
def timeout_error?(error)
|
237
|
+
full_error = error.inspect
|
238
|
+
# sample on JRuby + Tomcat JDBC :
|
239
|
+
# ActiveRecord::JDBCError(<The driver encountered an unknown error:
|
240
|
+
# org.apache.tomcat.jdbc.pool.PoolExhaustedException:
|
241
|
+
# [main] Timeout: Pool empty. Unable to fetch a connection in 2 seconds,
|
242
|
+
# none available[size:10; busy:10; idle:0; lastwait:2500].>
|
243
|
+
# )
|
244
|
+
return true if full_error =~ /timeout/i
|
245
|
+
# C3P0 :
|
246
|
+
# java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
|
247
|
+
return true if full_error =~ /timed.?out/i
|
248
|
+
# NOTE: not sure what to do on MRI and friends (C-pools not tested)
|
249
|
+
false
|
245
250
|
end
|
246
251
|
|
247
|
-
#
|
248
|
-
#
|
249
|
-
#
|
250
|
-
#
|
251
|
-
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
# end
|
255
|
-
# end if defined? ArJdbc
|
252
|
+
#def timeout_error?(error)
|
253
|
+
# if error.is_a?(JDBCError)
|
254
|
+
# if sql_exception = error.sql_exception
|
255
|
+
# return true if sql_exception.to_s =~ /timeout/i
|
256
|
+
# end
|
257
|
+
# end
|
258
|
+
#end if defined? ArJdbc
|
256
259
|
|
257
260
|
end
|
258
261
|
end
|
259
|
-
end
|
262
|
+
end
|
@@ -13,9 +13,29 @@ module ActiveRecord
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def current_connection_id
|
16
|
-
|
16
|
+
# NOTE: possible fiber work-around on JRuby ?!
|
17
|
+
Base.connection_id ||= Thread.current.object_id
|
17
18
|
end
|
18
19
|
|
20
|
+
# @note Method not part of the pre 4.0 API (does no exist).
|
21
|
+
def remove(conn)
|
22
|
+
synchronize do
|
23
|
+
@connections.delete conn
|
24
|
+
release conn
|
25
|
+
end
|
26
|
+
end if ActiveRecord::VERSION::MAJOR < 4
|
27
|
+
|
28
|
+
# clear_stale_cached_connections! without the deprecation :
|
29
|
+
def reap
|
30
|
+
keys = @reserved_connections.keys -
|
31
|
+
Thread.list.find_all { |t| t.alive? }.map(&:object_id)
|
32
|
+
keys.each do |key|
|
33
|
+
conn = @reserved_connections[key]
|
34
|
+
checkin conn
|
35
|
+
@reserved_connections.delete(key)
|
36
|
+
end
|
37
|
+
end if ActiveRecord::VERSION::MAJOR < 4
|
38
|
+
|
19
39
|
end
|
20
40
|
end
|
21
41
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'active_record/connection_adapters/abstract/connection_pool'
|
2
|
+
|
2
3
|
require 'thread'
|
3
4
|
require 'thread_safe'
|
4
5
|
require 'atomic'
|
5
6
|
|
7
|
+
require 'active_record/bogacs/pool_support'
|
8
|
+
|
6
9
|
# NOTE: needs explicit configuration - before connection gets established e.g.
|
7
10
|
#
|
8
11
|
# pool_class = ActiveRecord::ConnectionAdapters::ShareableConnectionPool
|
@@ -10,8 +13,9 @@ require 'atomic'
|
|
10
13
|
#
|
11
14
|
module ActiveRecord
|
12
15
|
module Bogacs
|
13
|
-
class ShareablePool < ConnectionAdapters::ConnectionPool #
|
16
|
+
class ShareablePool < ConnectionAdapters::ConnectionPool # NOTE: maybe do not override?!
|
14
17
|
include ThreadSafe::Util::CheapLockable
|
18
|
+
include PoolSupport
|
15
19
|
|
16
20
|
DEFAULT_SHARED_POOL = 0.25 # only allow 25% of the pool size to be shared
|
17
21
|
MAX_THREAD_SHARING = 5 # not really a strict limit but should hold
|
@@ -31,15 +35,14 @@ module ActiveRecord
|
|
31
35
|
|
32
36
|
# @override
|
33
37
|
def connection
|
34
|
-
|
35
|
-
Thread.current[:shared_pool_connection] || begin # super - simplified :
|
38
|
+
Thread.current[shared_connection_key] || begin # super - simplified :
|
36
39
|
super # @reserved_connections.compute_if_absent(current_connection_id) { checkout }
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
40
43
|
# @override
|
41
44
|
def active_connection?
|
42
|
-
if shared_conn = Thread.current[
|
45
|
+
if shared_conn = Thread.current[shared_connection_key]
|
43
46
|
return shared_conn.in_use?
|
44
47
|
end
|
45
48
|
super_active_connection? current_connection_id
|
@@ -95,8 +98,9 @@ module ActiveRecord
|
|
95
98
|
# Custom API :
|
96
99
|
|
97
100
|
def release_shared_connection(connection)
|
98
|
-
|
99
|
-
|
101
|
+
shared_conn_key = shared_connection_key
|
102
|
+
if connection == Thread.current[shared_conn_key]
|
103
|
+
Thread.current[shared_conn_key] = nil
|
100
104
|
end
|
101
105
|
|
102
106
|
@shared_connections.delete(connection)
|
@@ -104,8 +108,9 @@ module ActiveRecord
|
|
104
108
|
end
|
105
109
|
|
106
110
|
def with_shared_connection
|
111
|
+
shared_conn_key = shared_connection_key
|
107
112
|
# with_shared_connection call nested in the same thread
|
108
|
-
if connection = Thread.current[
|
113
|
+
if connection = Thread.current[shared_conn_key]
|
109
114
|
emulated_checkout(connection)
|
110
115
|
return yield connection
|
111
116
|
end
|
@@ -138,12 +143,12 @@ module ActiveRecord
|
|
138
143
|
shared = true
|
139
144
|
end
|
140
145
|
|
141
|
-
Thread.current[
|
146
|
+
Thread.current[shared_conn_key] = connection if shared
|
142
147
|
|
143
148
|
DEBUG && debug("with_shared_conn obtaining a connection took #{(Time.now - start) * 1000}ms")
|
144
149
|
yield connection
|
145
150
|
ensure
|
146
|
-
Thread.current[
|
151
|
+
Thread.current[shared_conn_key] = nil # if shared
|
147
152
|
rem_shared_connection(connection) if shared
|
148
153
|
end
|
149
154
|
end
|
@@ -162,10 +167,21 @@ module ActiveRecord
|
|
162
167
|
|
163
168
|
def acquire_connection_no_wait?
|
164
169
|
synchronize do
|
165
|
-
@available.send(:can_remove_no_wait?)
|
170
|
+
@connections.size < @size || @available.send(:can_remove_no_wait?)
|
171
|
+
#return true if @connections.size < @size
|
172
|
+
# @connections.size < @size || Queue#can_remove_no_wait? :
|
173
|
+
#queue = @available.instance_variable_get(:@queue)
|
174
|
+
#num_waiting = @available.instance_variable_get(:@num_waiting)
|
175
|
+
#queue.size > num_waiting
|
166
176
|
end
|
167
177
|
end
|
168
178
|
|
179
|
+
def acquire_connection_no_wait?
|
180
|
+
synchronize do
|
181
|
+
@connections.size < @size || @connections.any? { |c| ! c.in_use? }
|
182
|
+
end
|
183
|
+
end if ActiveRecord::VERSION::MAJOR < 4
|
184
|
+
|
169
185
|
# get a (shared) connection that is least shared among threads (or nil)
|
170
186
|
# nil gets returned if it's 'better' to checkout a new one to be shared
|
171
187
|
# ... to better utilize shared connection reuse among multiple threads
|
@@ -231,6 +247,10 @@ module ActiveRecord
|
|
231
247
|
connection.lease; # connection.verify! auto-reconnect should do this
|
232
248
|
end
|
233
249
|
|
250
|
+
def shared_connection_key
|
251
|
+
@shared_connection_key ||= :"shared_pool_connection##{object_id}"
|
252
|
+
end
|
253
|
+
|
234
254
|
DEBUG = begin
|
235
255
|
debug = ENV['DB_POOL_DEBUG'].to_s
|
236
256
|
if debug.to_s == 'false' then false
|
@@ -252,4 +272,4 @@ module ActiveRecord
|
|
252
272
|
|
253
273
|
end
|
254
274
|
end
|
255
|
-
end
|
275
|
+
end
|
@@ -12,10 +12,24 @@ module ActiveRecord
|
|
12
12
|
|
13
13
|
if method_defined? :in_use?
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
if method_defined? :last_use
|
16
|
+
|
17
|
+
def lease
|
18
|
+
unless in_use?
|
19
|
+
@owner = Thread.current
|
20
|
+
@in_use = true; @last_use = Time.now
|
21
|
+
end
|
18
22
|
end
|
23
|
+
|
24
|
+
else
|
25
|
+
|
26
|
+
def lease
|
27
|
+
unless in_use?
|
28
|
+
@owner = Thread.current
|
29
|
+
@in_use = true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
19
33
|
end
|
20
34
|
|
21
35
|
def expire
|
@@ -38,18 +52,6 @@ module ActiveRecord
|
|
38
52
|
|
39
53
|
end
|
40
54
|
|
41
|
-
alias :in_use? :owner
|
42
|
-
|
43
|
-
def lease
|
44
|
-
unless in_use?
|
45
|
-
@owner = Thread.current
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def expire
|
50
|
-
@owner = nil
|
51
|
-
end
|
52
|
-
|
53
55
|
end
|
54
56
|
|
55
57
|
end
|
@@ -14,54 +14,72 @@ module ActiveRecord
|
|
14
14
|
# extend Bogacs::TestHelper
|
15
15
|
extend Bogacs::JndiTestHelper
|
16
16
|
|
17
|
+
@@data_source = nil
|
18
|
+
|
17
19
|
def self.startup
|
18
20
|
return if self == TestBase
|
19
21
|
|
20
|
-
ActiveRecord::Base.establish_connection AR_CONFIG
|
21
|
-
|
22
|
-
ActiveRecord::Base.connection.jdbc_connection # force connection
|
23
|
-
current_config = Bogacs::TestHelper.current_connection_config
|
24
|
-
|
25
|
-
ActiveRecord::Base.connection_pool.disconnect!
|
26
|
-
|
27
|
-
setup_jdbc_context
|
28
|
-
bind_data_source init_data_source current_config
|
29
|
-
|
30
22
|
ConnectionAdapters::ConnectionHandler.connection_pool_class = FalsePool
|
31
|
-
|
23
|
+
|
24
|
+
establish_jndi_connection
|
32
25
|
end
|
33
26
|
|
34
27
|
def self.shutdown
|
35
28
|
return if self == TestBase
|
36
29
|
|
30
|
+
close_data_source
|
31
|
+
|
37
32
|
ActiveRecord::Base.connection_pool.disconnect!
|
38
33
|
ConnectionAdapters::ConnectionHandler.connection_pool_class = ConnectionAdapters::ConnectionPool
|
39
34
|
end
|
40
35
|
|
41
|
-
|
36
|
+
@@raw_config = nil
|
42
37
|
|
43
|
-
|
38
|
+
def self.raw_config
|
39
|
+
@@raw_config ||= begin
|
40
|
+
ActiveRecord::Base.establish_connection AR_CONFIG
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
ActiveRecord::Base.connection.jdbc_connection # force connection
|
43
|
+
current_config = Bogacs::TestHelper.current_connection_config
|
44
|
+
|
45
|
+
ActiveRecord::Base.connection_pool.disconnect!
|
46
|
+
|
47
|
+
current_config
|
48
|
+
end
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
+
def self.init_data_source
|
52
|
+
setup_jdbc_context
|
53
|
+
bind_data_source @@data_source = build_data_source(raw_config)
|
54
|
+
end
|
51
55
|
|
52
|
-
def
|
53
|
-
|
56
|
+
def self.establish_jndi_connection
|
57
|
+
if ActiveRecord::Base.connected?
|
58
|
+
ActiveRecord::Base.clear_all_connections!
|
59
|
+
close_data_source
|
60
|
+
end
|
61
|
+
|
62
|
+
init_data_source
|
63
|
+
ActiveRecord::Base.establish_connection jndi_config
|
54
64
|
end
|
55
65
|
|
56
|
-
def
|
57
|
-
@@data_source.
|
66
|
+
def self.close_data_source
|
67
|
+
@@data_source.close if @@data_source
|
58
68
|
end
|
59
69
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
70
|
+
def data_source; @@data_source end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
module ConnectionPoolWrappingDataSourceTestMethods
|
75
|
+
include ConnectionAdapters::ConnectionPoolTestMethods
|
76
|
+
|
77
|
+
def setup
|
78
|
+
@pool = FalsePool.new ActiveRecord::Base.connection_pool.spec
|
63
79
|
end
|
64
80
|
|
81
|
+
def max_pool_size; raise "#{__method__} not implemented" end
|
82
|
+
|
65
83
|
# adjust ConnectionAdapters::ConnectionPoolTestMethods :
|
66
84
|
|
67
85
|
undef :test_checkout_fairness
|
@@ -75,6 +93,11 @@ module ActiveRecord
|
|
75
93
|
|
76
94
|
undef :test_removing_releases_latch
|
77
95
|
|
96
|
+
def test_uses_false_pool_and_can_execute_query
|
97
|
+
assert_instance_of ActiveRecord::Bogacs::FalsePool, ActiveRecord::Base.connection_pool
|
98
|
+
assert ActiveRecord::Base.connection.exec_query('SELECT 42')
|
99
|
+
end
|
100
|
+
|
78
101
|
# @override
|
79
102
|
def test_remove_connection
|
80
103
|
conn = pool.checkout
|
@@ -92,7 +115,7 @@ module ActiveRecord
|
|
92
115
|
def test_full_pool_exception
|
93
116
|
# ~ pool_size.times { pool.checkout }
|
94
117
|
threads_ready = Queue.new; threads_block = Atomic.new(0); threads = []
|
95
|
-
|
118
|
+
max_pool_size.times do |i|
|
96
119
|
threads << Thread.new do
|
97
120
|
begin
|
98
121
|
conn = ActiveRecord::Base.connection
|
@@ -108,7 +131,7 @@ module ActiveRecord
|
|
108
131
|
end
|
109
132
|
end
|
110
133
|
end
|
111
|
-
|
134
|
+
max_pool_size.times { threads_ready.pop } # awaits
|
112
135
|
|
113
136
|
assert_raise(ConnectionTimeoutError) do
|
114
137
|
ActiveRecord::Base.connection # ~ pool.checkout
|
@@ -136,7 +159,7 @@ module ActiveRecord
|
|
136
159
|
end
|
137
160
|
|
138
161
|
threads_ready = Queue.new; threads_block = Atomic.new(0); threads = []
|
139
|
-
(
|
162
|
+
(max_pool_size - 1).times do |i|
|
140
163
|
threads << Thread.new do
|
141
164
|
begin
|
142
165
|
conn = ActiveRecord::Base.connection
|
@@ -152,7 +175,7 @@ module ActiveRecord
|
|
152
175
|
end
|
153
176
|
end
|
154
177
|
end
|
155
|
-
(
|
178
|
+
(max_pool_size - 1).times { threads_ready.pop } # awaits
|
156
179
|
|
157
180
|
connection = t1_ready.pop
|
158
181
|
t1_jdbc_connection = connection.jdbc_connection(true)
|
@@ -189,9 +212,96 @@ module ActiveRecord
|
|
189
212
|
threads && threads.each(&:join)
|
190
213
|
end
|
191
214
|
|
192
|
-
|
215
|
+
end
|
193
216
|
|
194
|
-
|
217
|
+
class ConnectionPoolWrappingTomcatJdbcDataSourceTest < TestBase
|
218
|
+
include ConnectionPoolWrappingDataSourceTestMethods
|
219
|
+
|
220
|
+
def self.build_data_source(config)
|
221
|
+
build_tomcat_jdbc_data_source(config)
|
222
|
+
end
|
223
|
+
|
224
|
+
def self.jndi_name; 'jdbc/TestTomcatJdbcDB' end
|
225
|
+
|
226
|
+
def self.close_data_source
|
227
|
+
@@data_source.send(:close, true) if @@data_source
|
228
|
+
end
|
229
|
+
|
230
|
+
def max_pool_size; @@data_source.max_active end
|
231
|
+
|
232
|
+
def teardown
|
233
|
+
self.class.close_data_source
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
class ConnectionPoolWrappingC3P0DataSourceTest < TestBase
|
239
|
+
include ConnectionPoolWrappingDataSourceTestMethods
|
240
|
+
|
241
|
+
def self.build_data_source(config)
|
242
|
+
build_c3p0_data_source(config)
|
243
|
+
end
|
244
|
+
|
245
|
+
def self.jndi_config
|
246
|
+
config = super
|
247
|
+
config[:connection_alive_sql] = 'SELECT 1' if old_c3p0?
|
248
|
+
config
|
249
|
+
end
|
250
|
+
|
251
|
+
def self.old_c3p0?
|
252
|
+
if c3p0_jar = $CLASSPATH.find { |jar| jar =~ /c3p0/ }
|
253
|
+
if match = File.basename(c3p0_jar).match(/c3p0\-(.*).jar/)
|
254
|
+
return true if match[1] <= '0.9.2.1'
|
255
|
+
end
|
256
|
+
return false
|
257
|
+
end
|
258
|
+
nil
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_full_pool_blocks
|
262
|
+
return if self.class.old_c3p0?
|
263
|
+
super
|
264
|
+
end
|
265
|
+
|
266
|
+
def self.jndi_name; 'jdbc/TestC3P0DB' end
|
267
|
+
|
268
|
+
def max_pool_size; @@data_source.max_pool_size end
|
269
|
+
|
270
|
+
def teardown
|
271
|
+
# self.class.close_data_source # @@data_source = nil
|
272
|
+
self.class.establish_jndi_connection # for next test
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
class ConnectionPoolWrappingHikariDataSourceTest < TestBase
|
278
|
+
include ConnectionPoolWrappingDataSourceTestMethods
|
279
|
+
|
280
|
+
def self.build_data_source(config)
|
281
|
+
data_source = build_hikari_data_source(config)
|
282
|
+
|
283
|
+
com.zaxxer.hikari.HikariDataSource.class_eval do
|
284
|
+
field_reader :pool unless method_defined? :pool
|
285
|
+
end
|
286
|
+
com.zaxxer.hikari.pool.HikariPool.class_eval do
|
287
|
+
field_reader :isShutdown unless method_defined? :isShutdown
|
288
|
+
end
|
289
|
+
|
290
|
+
data_source
|
291
|
+
end
|
292
|
+
|
293
|
+
def self.jndi_name; 'jdbc/TestHikariDB' end
|
294
|
+
|
295
|
+
def max_pool_size; @@data_source.maximum_pool_size end
|
296
|
+
|
297
|
+
|
298
|
+
def self.close_data_source
|
299
|
+
@@data_source.shutdown if @@data_source
|
300
|
+
end
|
301
|
+
|
302
|
+
def teardown
|
303
|
+
self.class.establish_jndi_connection # for next test
|
304
|
+
end
|
195
305
|
|
196
306
|
end
|
197
307
|
|
@@ -160,7 +160,7 @@ module ActiveRecord
|
|
160
160
|
def test_does_not_use_more_shared_connections_than_configured_shared_size
|
161
161
|
shared_conn_threads = {}
|
162
162
|
begin
|
163
|
-
block_connections_in_threads(
|
163
|
+
block_connections_in_threads(4) do # 6 (out of 10) connections left
|
164
164
|
|
165
165
|
shared_conn_threads = start_shared_connection_threads(7, :wait)
|
166
166
|
|
@@ -170,6 +170,7 @@ module ActiveRecord
|
|
170
170
|
assert shared_connection?(conn)
|
171
171
|
conn
|
172
172
|
end
|
173
|
+
|
173
174
|
assert_equal 5, shared_conns.uniq.size
|
174
175
|
|
175
176
|
# still one left for normal connections :
|
@@ -290,7 +291,7 @@ module ActiveRecord
|
|
290
291
|
protected
|
291
292
|
|
292
293
|
def current_shared_pool_connection
|
293
|
-
Thread.current[:
|
294
|
+
Thread.current[ connection_pool.send(:shared_connection_key) ]
|
294
295
|
end
|
295
296
|
|
296
297
|
def set_pool_size(size, shared_size = nil)
|
@@ -9,8 +9,9 @@ module ActiveRecord
|
|
9
9
|
def config; AR_CONFIG end
|
10
10
|
|
11
11
|
def setup
|
12
|
-
super
|
12
|
+
super; require 'active_record/bogacs/pool_support'
|
13
13
|
@pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
|
14
|
+
@pool.extend Bogacs::PoolSupport # aligns API for AR < 4.0
|
14
15
|
end
|
15
16
|
|
16
17
|
end
|
@@ -160,7 +160,11 @@ module ActiveRecord
|
|
160
160
|
def test_active_connection?
|
161
161
|
assert_false pool.active_connection?
|
162
162
|
assert pool.connection
|
163
|
-
|
163
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
164
|
+
assert_true pool.active_connection?
|
165
|
+
else
|
166
|
+
assert pool.active_connection?
|
167
|
+
end
|
164
168
|
pool.release_connection
|
165
169
|
assert_false pool.active_connection?
|
166
170
|
end
|
data/test/test_helper.rb
CHANGED
@@ -19,6 +19,7 @@ ENV['DB_POOL_SHARED'] ||= 0.5.to_s
|
|
19
19
|
# e.g. 40 - ( 40 * 0.75 ) * 5 = 160
|
20
20
|
|
21
21
|
require 'active_record'
|
22
|
+
require 'arjdbc' if defined? JRUBY_VERSION
|
22
23
|
|
23
24
|
require 'logger'
|
24
25
|
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
@@ -40,6 +41,7 @@ config[:'password'] = ENV['AR_PASSWORD'] if ENV['AR_PASSWORD']
|
|
40
41
|
if url = ENV['AR_URL'] || ENV['JDBC_URL']
|
41
42
|
config[:'url'] = url
|
42
43
|
else
|
44
|
+
config[:'host'] = ENV['AR_HOST'] || 'localhost'
|
43
45
|
config[:'database'] = ENV['AR_DATABASE'] || 'ar_basin'
|
44
46
|
end
|
45
47
|
|
@@ -211,7 +213,9 @@ module ActiveRecord
|
|
211
213
|
|
212
214
|
module JndiTestHelper
|
213
215
|
|
214
|
-
|
216
|
+
@@setup_jdbc_context = nil
|
217
|
+
|
218
|
+
def setup_jdbc_context!
|
215
219
|
load 'test/jars/tomcat-juli.jar'
|
216
220
|
load 'test/jars/tomcat-catalina.jar'
|
217
221
|
|
@@ -231,18 +235,23 @@ module ActiveRecord
|
|
231
235
|
end
|
232
236
|
end
|
233
237
|
|
234
|
-
def
|
238
|
+
def setup_jdbc_context
|
239
|
+
@@setup_jdbc_context || setup_jdbc_context!
|
240
|
+
@@setup_jdbc_context = true
|
241
|
+
end
|
242
|
+
|
243
|
+
def build_tomcat_jdbc_data_source(ar_jdbc_config = AR_CONFIG)
|
235
244
|
load 'test/jars/tomcat-jdbc.jar'
|
236
245
|
|
237
246
|
data_source = org.apache.tomcat.jdbc.pool.DataSource.new
|
238
|
-
|
247
|
+
configure_dbcp_data_source(data_source, ar_jdbc_config)
|
239
248
|
|
240
249
|
data_source.setJmxEnabled false
|
241
250
|
|
242
251
|
data_source
|
243
252
|
end
|
244
253
|
|
245
|
-
def
|
254
|
+
def configure_dbcp_data_source(data_source, ar_jdbc_config)
|
246
255
|
unless driver = ar_jdbc_config[:driver]
|
247
256
|
jdbc_driver_module.load_driver
|
248
257
|
driver = jdbc_driver_module.driver_name
|
@@ -275,11 +284,125 @@ module ActiveRecord
|
|
275
284
|
#data_source.setRemoveAbandoned false
|
276
285
|
#data_source.setLogAbandoned true
|
277
286
|
end
|
278
|
-
private :
|
287
|
+
private :configure_dbcp_data_source
|
288
|
+
|
289
|
+
def build_c3p0_data_source(ar_jdbc_config = AR_CONFIG)
|
290
|
+
Dir.glob('test/jars/{c3p0,mchange-commons}*.jar').each { |jar| load jar }
|
291
|
+
|
292
|
+
data_source = com.mchange.v2.c3p0.ComboPooledDataSource.new
|
293
|
+
configure_c3p0_data_source(data_source, ar_jdbc_config)
|
294
|
+
|
295
|
+
data_source
|
296
|
+
end
|
297
|
+
|
298
|
+
def configure_c3p0_data_source(data_source, ar_jdbc_config)
|
299
|
+
unless driver = ar_jdbc_config[:driver]
|
300
|
+
jdbc_driver_module.load_driver
|
301
|
+
driver = jdbc_driver_module.driver_name
|
302
|
+
end
|
303
|
+
|
304
|
+
data_source.setDriverClass driver
|
305
|
+
data_source.setJdbcUrl ar_jdbc_config[:url]
|
306
|
+
if user = ar_jdbc_config[:username]
|
307
|
+
# data_source.setUser user # WTF C3P0
|
308
|
+
data_source.setOverrideDefaultUser user
|
309
|
+
end
|
310
|
+
data_source.setPassword ar_jdbc_config[:password] if ar_jdbc_config[:password]
|
311
|
+
|
312
|
+
if ar_jdbc_config[:properties]
|
313
|
+
properties = java.util.Properties.new
|
314
|
+
properties.putAll ar_jdbc_config[:properties]
|
315
|
+
data_source.setProperties properties
|
316
|
+
end
|
317
|
+
# JDBC pool tunings (some mapped from AR configuration) :
|
318
|
+
if ar_jdbc_config[:pool] # default is 100
|
319
|
+
data_source.setMaxPoolSize ar_jdbc_config[:pool].to_i
|
320
|
+
if prefill = ar_jdbc_config[:pool_prefill]
|
321
|
+
data_source.setInitialPoolSize prefill.to_i
|
322
|
+
end
|
323
|
+
end
|
324
|
+
checkout_timeout = ar_jdbc_config[:checkout_timeout] || 5
|
325
|
+
data_source.setCheckoutTimeout checkout_timeout * 1000
|
326
|
+
|
327
|
+
data_source.setAcquireIncrement 1 # default 3
|
328
|
+
data_source.setAcquireRetryAttempts 3 # default 30
|
329
|
+
data_source.setAcquireRetryDelay 1000 # default 1000
|
330
|
+
data_source.setNumHelperThreads 2 # default 3
|
331
|
+
end
|
332
|
+
private :configure_c3p0_data_source
|
333
|
+
|
334
|
+
|
335
|
+
def build_hikari_data_source(ar_jdbc_config = AR_CONFIG)
|
336
|
+
Dir.glob('test/jars/{javassist,slf4j,HikariCP}*.jar').each { |jar| load jar }
|
337
|
+
|
338
|
+
configure_hikari_data_source(ar_jdbc_config)
|
339
|
+
end
|
340
|
+
|
341
|
+
def configure_hikari_data_source(ar_jdbc_config)
|
342
|
+
hikari_config = com.zaxxer.hikari.HikariConfig.new
|
343
|
+
|
344
|
+
unless driver = ar_jdbc_config[:driver]
|
345
|
+
jdbc_driver_module.load_driver
|
346
|
+
driver = jdbc_driver_module.driver_name
|
347
|
+
end
|
348
|
+
|
349
|
+
case driver
|
350
|
+
when /mysql/i
|
351
|
+
hikari_config.setDataSourceClassName 'com.mysql.jdbc.jdbc2.optional.MysqlDataSource'
|
352
|
+
hikari_config.addDataSourceProperty 'serverName', ar_jdbc_config[:host] || 'localhost'
|
353
|
+
hikari_config.addDataSourceProperty 'databaseName', ar_jdbc_config[:database]
|
354
|
+
hikari_config.addDataSourceProperty 'port', ar_jdbc_config[:port] if ar_jdbc_config[:port]
|
355
|
+
if true
|
356
|
+
hikari_config.addDataSourceProperty 'user', ar_jdbc_config[:username] || 'root'
|
357
|
+
end
|
358
|
+
if ar_jdbc_config[:password]
|
359
|
+
hikari_config.addDataSourceProperty 'password', ar_jdbc_config[:password]
|
360
|
+
end
|
361
|
+
when /postgres/i
|
362
|
+
hikari_config.setDataSourceClassName 'org.postgresql.ds.PGSimpleDataSource'
|
363
|
+
hikari_config.addDataSourceProperty 'serverName', ar_jdbc_config[:host] || 'localhost'
|
364
|
+
hikari_config.addDataSourceProperty 'databaseName', ar_jdbc_config[:database]
|
365
|
+
hikari_config.addDataSourceProperty 'port', ar_jdbc_config[:port] if ar_jdbc_config[:port]
|
366
|
+
if ar_jdbc_config[:username]
|
367
|
+
hikari_config.addDataSourceProperty 'user', ar_jdbc_config[:username]
|
368
|
+
end
|
369
|
+
if ar_jdbc_config[:password]
|
370
|
+
hikari_config.addDataSourceProperty 'password', ar_jdbc_config[:password]
|
371
|
+
end
|
372
|
+
else
|
373
|
+
hikari_config.setDriverClassName driver
|
374
|
+
hikari_config.setJdbcUrl ar_jdbc_config[:url]
|
375
|
+
hikari_config.setUsername ar_jdbc_config[:username] if ar_jdbc_config[:username]
|
376
|
+
hikari_config.setPassword ar_jdbc_config[:password] if ar_jdbc_config[:password]
|
377
|
+
end
|
378
|
+
|
379
|
+
# TODO: we shall handle raw properties ?!
|
380
|
+
#if ar_jdbc_config[:properties]
|
381
|
+
# properties = java.util.Properties.new
|
382
|
+
# properties.putAll ar_jdbc_config[:properties]
|
383
|
+
# hikari_config.setProperties properties
|
384
|
+
#end
|
385
|
+
|
386
|
+
# JDBC pool tunings (some mapped from AR configuration) :
|
387
|
+
if ar_jdbc_config[:pool] # default is 100
|
388
|
+
hikari_config.setMaximumPoolSize ar_jdbc_config[:pool].to_i
|
389
|
+
if prefill = ar_jdbc_config[:pool_prefill]
|
390
|
+
hikari_config.setMinConnectionsPerPartition prefill.to_i
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
checkout_timeout = ar_jdbc_config[:checkout_timeout] || 5
|
395
|
+
hikari_config.setConnectionTimeout checkout_timeout * 1000
|
396
|
+
|
397
|
+
hikari_config.setLeakDetectionThreshold 30 * 1000 # default 10s
|
398
|
+
|
399
|
+
com.zaxxer.hikari.HikariDataSource.new hikari_config
|
400
|
+
end
|
401
|
+
private :configure_hikari_data_source
|
279
402
|
|
280
403
|
def bind_data_source(data_source, jndi_name = jndi_config[:jndi])
|
281
404
|
load_driver
|
282
|
-
javax.naming.InitialContext.new.
|
405
|
+
javax.naming.InitialContext.new.rebind jndi_name, data_source
|
283
406
|
end
|
284
407
|
|
285
408
|
def load_driver
|
@@ -289,6 +412,7 @@ module ActiveRecord
|
|
289
412
|
def jdbc_driver_module
|
290
413
|
driver = jndi_config[:adapter]
|
291
414
|
driver = 'postgres' if driver == 'postgresql'
|
415
|
+
driver = 'mysql' if driver == 'mysql2'
|
292
416
|
require "jdbc/#{driver}"
|
293
417
|
::Jdbc.const_get ::Jdbc.constants.first
|
294
418
|
end
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karol Bucek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: atomic
|