activerecord-bogacs 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|