seamless_database_pool 1.0.17 → 1.0.18
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/.gitignore +2 -0
- data/.travis.yml +5 -0
- data/HISTORY.txt +79 -0
- data/Rakefile +1 -24
- data/VERSION +1 -0
- data/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb +4 -4
- data/seamless_database_pool.gemspec +21 -0
- data/spec/connection_statistics_spec.rb +1 -1
- data/spec/database.yml +1 -0
- data/spec/seamless_database_pool_adapter_spec.rb +70 -68
- data/spec/spec_helper.rb +12 -0
- metadata +26 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97df06be58768fd03235c0370d3f6e48a997f720
|
4
|
+
data.tar.gz: 4175c26ce145bc7e429f7b996a72fda489450506
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fab0026bafa0d44e418d1522f0d6ee584b9fcaaa01af1fffe2a3388c93ff52b841656e2e68487d7e7b58ae4bfd757a8532d197157f5e7a677400c37d0bf48092
|
7
|
+
data.tar.gz: cdb1f53c64c9798e252ad7016d04d3fc5c771195cba4a6745a7b31eee5fa8d8c68def54dfc94db7b23e6bb83b287d4546423bbd03916374be85f7092bc6c8f87
|
data/.gitignore
ADDED
data/HISTORY.txt
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
1.0.18
|
2
|
+
|
3
|
+
ActiveRecord 5.0 compatibility (thanks jkowens)
|
4
|
+
|
5
|
+
1.0.17
|
6
|
+
|
7
|
+
Do not update the HTTP session if there are no changes.
|
8
|
+
|
9
|
+
1.0.16
|
10
|
+
|
11
|
+
Use shorter to_s output for output on connection.inspect.
|
12
|
+
|
13
|
+
1.0.15
|
14
|
+
|
15
|
+
Implement less wordy connection to string method so logs don't fill up with long messages on connection errors.
|
16
|
+
|
17
|
+
Update specs to remove deprecation warnings
|
18
|
+
|
19
|
+
Fix adapter specs to work with ActiveRecord 4.1 configuration changes
|
20
|
+
|
21
|
+
1.0.14
|
22
|
+
|
23
|
+
Remove custom connection timeout logic; Use the underlying driver's timeouts instead.
|
24
|
+
|
25
|
+
Fix to work with query cache.
|
26
|
+
|
27
|
+
Make driver less aggressive about overriding methods to proxy to the master connection.
|
28
|
+
|
29
|
+
End support for ActiveRecord 2.x
|
30
|
+
|
31
|
+
Add support for ActiveRecord 4.0
|
32
|
+
|
33
|
+
1.0.13
|
34
|
+
|
35
|
+
Fix to work with `rake db:*` Rails tasks by removing the adapter from the configuration when db:* tasks are run.
|
36
|
+
|
37
|
+
Fix connection pool issues so checkout/checkins don't interact with the underlying connections (thanks afex)
|
38
|
+
|
39
|
+
Ruby 2.0/Rails 4.0 compatibility (thanks t27duck)
|
40
|
+
|
41
|
+
1.0.12
|
42
|
+
|
43
|
+
Remove excessively long log messages on reconnect attempts.
|
44
|
+
|
45
|
+
1.0.11
|
46
|
+
|
47
|
+
Remove debug code that prevented recovering from errors.
|
48
|
+
|
49
|
+
1.0.10
|
50
|
+
|
51
|
+
Compatibility with ActiveRecord 3.1.0
|
52
|
+
|
53
|
+
1.0.9
|
54
|
+
|
55
|
+
Compatibility with bind variables.
|
56
|
+
|
57
|
+
1.0.8
|
58
|
+
|
59
|
+
Compatibility with ActiveRecord 3.1.0rc4
|
60
|
+
|
61
|
+
1.0.7
|
62
|
+
|
63
|
+
Make compatible with ActionController 3.0
|
64
|
+
|
65
|
+
Improved handling of down slave instances.
|
66
|
+
|
67
|
+
1.0.6
|
68
|
+
|
69
|
+
Make compatible with ActiveRecord 3.0.
|
70
|
+
|
71
|
+
Make compatible with database adapters other than MySQL including PostgrSQL.
|
72
|
+
|
73
|
+
Better test suite to actually hit three different database adapters.
|
74
|
+
|
75
|
+
1.0.5
|
76
|
+
|
77
|
+
Update docs.
|
78
|
+
|
79
|
+
Remove rake dependency on rspec
|
data/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
require 'yaml'
|
4
|
+
require "bundler/gem_tasks"
|
4
5
|
|
5
6
|
desc 'Default: run unit tests.'
|
6
7
|
task :default => :test
|
@@ -59,27 +60,3 @@ rescue LoadError
|
|
59
60
|
STDERR.puts "You must have rspec >= 2.0 to run the tests"
|
60
61
|
end
|
61
62
|
end
|
62
|
-
|
63
|
-
begin
|
64
|
-
require 'jeweler'
|
65
|
-
Jeweler::Tasks.new do |gem|
|
66
|
-
gem.name = "seamless_database_pool"
|
67
|
-
gem.summary = "Add support for master/slave database clusters in ActiveRecord to improve performance."
|
68
|
-
gem.email = "bbdurand@gmail.com"
|
69
|
-
gem.homepage = "http://github.com/bdurand/seamless_database_pool"
|
70
|
-
gem.authors = ["Brian Durand"]
|
71
|
-
gem.files = FileList["lib/**/*", "spec/**/*", "README.rdoc", "Rakefile", "MIT-LICENSE"].to_a
|
72
|
-
gem.has_rdoc = true
|
73
|
-
gem.extra_rdoc_files = ["README.rdoc", "MIT-LICENSE"]
|
74
|
-
|
75
|
-
gem.add_dependency('activerecord', '>= 3.0.20')
|
76
|
-
gem.add_development_dependency('rspec', '>= 2.0')
|
77
|
-
gem.add_development_dependency('jeweler')
|
78
|
-
gem.add_development_dependency('sqlite3')
|
79
|
-
gem.add_development_dependency('mysql')
|
80
|
-
gem.add_development_dependency('pg')
|
81
|
-
end
|
82
|
-
|
83
|
-
Jeweler::GemcutterTasks.new
|
84
|
-
rescue LoadError
|
85
|
-
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.18
|
@@ -35,7 +35,7 @@ module ActiveRecord
|
|
35
35
|
end if config[:read_pool]
|
36
36
|
|
37
37
|
klass = ::ActiveRecord::ConnectionAdapters::SeamlessDatabasePoolAdapter.adapter_class(master_connection)
|
38
|
-
klass.new(nil, logger, master_connection, read_connections, pool_weights)
|
38
|
+
klass.new(nil, logger, master_connection, read_connections, pool_weights, config)
|
39
39
|
end
|
40
40
|
|
41
41
|
def establish_adapter(adapter)
|
@@ -153,12 +153,12 @@ module ActiveRecord
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
-
def initialize(connection, logger, master_connection, read_connections, pool_weights)
|
156
|
+
def initialize(connection, logger, master_connection, read_connections, pool_weights, config)
|
157
157
|
@master_connection = master_connection
|
158
158
|
@read_connections = read_connections.dup.freeze
|
159
159
|
|
160
|
-
super(connection, logger)
|
161
|
-
|
160
|
+
super(connection, logger, config)
|
161
|
+
|
162
162
|
@weighted_read_connections = []
|
163
163
|
pool_weights.each_pair do |conn, weight|
|
164
164
|
weight.times{@weighted_read_connections << conn}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "seamless_database_pool"
|
3
|
+
spec.version = File.read(File.expand_path("../VERSION", __FILE__)).chomp
|
4
|
+
spec.authors = ["Brian Durand"]
|
5
|
+
spec.email = ["bbdurand@gmail.com"]
|
6
|
+
spec.description = %q{Add support for master/slave database database clusters in ActiveRecord to improve performance.}
|
7
|
+
spec.summary = %q{Add support for master/slave database clusters in ActiveRecord to improve performance.}
|
8
|
+
spec.homepage = "https://github.com/bdurand/seamless_database_pool"
|
9
|
+
spec.license = "MIT"
|
10
|
+
|
11
|
+
spec.files = `git ls-files`.split($/)
|
12
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
13
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
14
|
+
spec.require_paths = ["lib"]
|
15
|
+
|
16
|
+
spec.add_runtime_dependency(%q<activerecord>, [">= 3.0.20"])
|
17
|
+
spec.add_development_dependency(%q<rspec>, [">= 2.0"])
|
18
|
+
spec.add_development_dependency(%q<sqlite3>, [">= 0"])
|
19
|
+
spec.add_development_dependency(%q<mysql>, [">= 0"])
|
20
|
+
spec.add_development_dependency(%q<pg>, [">= 0"])
|
21
|
+
end
|
@@ -61,7 +61,7 @@ describe SeamlessDatabasePool::ConnectionStatistics do
|
|
61
61
|
|
62
62
|
it "should increment counts only once within a block" do
|
63
63
|
connection = SeamlessDatabasePool::ConnectionStatisticsTester.new
|
64
|
-
connection.
|
64
|
+
expect(connection).to receive(:execute).with('SQL')
|
65
65
|
connection.update('SQL')
|
66
66
|
connection.connection_statistics.should == {:update => 1}
|
67
67
|
end
|
data/spec/database.yml
CHANGED
@@ -58,16 +58,16 @@ describe "SeamlessDatabasePoolAdapter ActiveRecord::Base extension" do
|
|
58
58
|
logger = ActiveRecord::Base.logger
|
59
59
|
weights = {master_connection => 1, read_connection_1 => 1, read_connection_2 => 2}
|
60
60
|
|
61
|
-
ActiveRecord::Base.
|
62
|
-
ActiveRecord::Base.
|
63
|
-
ActiveRecord::Base.
|
61
|
+
expect(ActiveRecord::Base).to receive(:writer_connection).with('adapter' => 'writer', 'host' => 'master_host', 'username' => 'user', 'pool_weight' => 1).and_return(master_connection)
|
62
|
+
expect(ActiveRecord::Base).to receive(:reader_connection).with('adapter' => 'reader', 'host' => 'read_host_1', 'username' => 'user', 'pool_weight' => 1).and_return(read_connection_1)
|
63
|
+
expect(ActiveRecord::Base).to receive(:reader_connection).with('adapter' => 'reader', 'host' => 'read_host_2', 'username' => 'user', 'pool_weight' => 2).and_return(read_connection_2)
|
64
64
|
|
65
65
|
klass = double(:class)
|
66
|
-
ActiveRecord::ConnectionAdapters::SeamlessDatabasePoolAdapter.
|
67
|
-
klass.
|
66
|
+
expect(ActiveRecord::ConnectionAdapters::SeamlessDatabasePoolAdapter).to receive(:adapter_class).with(master_connection).and_return(klass)
|
67
|
+
expect(klass).to receive(:new).with(nil, logger, master_connection, [read_connection_1, read_connection_2], weights, options).and_return(pool_connection)
|
68
68
|
|
69
|
-
ActiveRecord::Base.
|
70
|
-
ActiveRecord::Base.
|
69
|
+
expect(ActiveRecord::Base).to receive(:establish_adapter).with('writer')
|
70
|
+
expect(ActiveRecord::Base).to receive(:establish_adapter).with('reader').twice
|
71
71
|
|
72
72
|
ActiveRecord::Base.seamless_database_pool_connection(options).should == pool_connection
|
73
73
|
end
|
@@ -82,10 +82,11 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
82
82
|
let(:master_connection){ SeamlessDatabasePool::MockMasterConnection.new("master") }
|
83
83
|
let(:read_connection_1){ SeamlessDatabasePool::MockConnection.new("read_1") }
|
84
84
|
let(:read_connection_2){ SeamlessDatabasePool::MockConnection.new("read_2") }
|
85
|
+
let(:config){ {} }
|
85
86
|
let(:pool_connection) do
|
86
87
|
weights = {master_connection => 1, read_connection_1 => 1, read_connection_2 => 2}
|
87
88
|
connection_class = ActiveRecord::ConnectionAdapters::SeamlessDatabasePoolAdapter.adapter_class(master_connection)
|
88
|
-
connection_class.new(nil, nil, master_connection, [read_connection_1, read_connection_2], weights)
|
89
|
+
connection_class.new(nil, nil, master_connection, [read_connection_1, read_connection_2], weights, config)
|
89
90
|
end
|
90
91
|
|
91
92
|
it "should be able to be converted to a string" do
|
@@ -104,26 +105,26 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
104
105
|
end
|
105
106
|
|
106
107
|
it "should return the current read connection" do
|
107
|
-
SeamlessDatabasePool.
|
108
|
+
expect(SeamlessDatabasePool).to receive(:read_only_connection).with(pool_connection).and_return(:current)
|
108
109
|
pool_connection.current_read_connection.should == :current
|
109
110
|
end
|
110
111
|
|
111
112
|
it "should select a random read connection" do
|
112
113
|
mock_connection = double(:connection)
|
113
114
|
mock_connection.stub(:active? => true)
|
114
|
-
pool_connection.
|
115
|
-
pool_connection.
|
115
|
+
expect(pool_connection).to receive(:available_read_connections).and_return([:fake1, :fake2, mock_connection])
|
116
|
+
expect(pool_connection).to receive(:rand).with(3).and_return(2)
|
116
117
|
pool_connection.random_read_connection.should == mock_connection
|
117
118
|
end
|
118
119
|
|
119
120
|
it "should select the master connection if the read pool is empty" do
|
120
|
-
pool_connection.
|
121
|
+
expect(pool_connection).to receive(:available_read_connections).and_return([])
|
121
122
|
pool_connection.random_read_connection.should == master_connection
|
122
123
|
end
|
123
124
|
|
124
125
|
it "should use the master connection in a block" do
|
125
126
|
connection_class = ActiveRecord::ConnectionAdapters::SeamlessDatabasePoolAdapter.adapter_class(master_connection)
|
126
|
-
connection = connection_class.new(nil, double(:logger), master_connection, [read_connection_1], {read_connection_1 => 1})
|
127
|
+
connection = connection_class.new(nil, double(:logger), master_connection, [read_connection_1], {read_connection_1 => 1}, config)
|
127
128
|
connection.random_read_connection.should == read_connection_1
|
128
129
|
connection.use_master_connection do
|
129
130
|
connection.random_read_connection.should == master_connection
|
@@ -133,12 +134,12 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
133
134
|
|
134
135
|
it "should use the master connection inside a transaction" do
|
135
136
|
connection_class = ActiveRecord::ConnectionAdapters::SeamlessDatabasePoolAdapter.adapter_class(master_connection)
|
136
|
-
connection = connection_class.new(nil, double(:logger), master_connection, [read_connection_1], {read_connection_1 => 1})
|
137
|
-
master_connection.
|
138
|
-
master_connection.
|
139
|
-
master_connection.
|
140
|
-
read_connection_1.
|
141
|
-
read_connection_1.
|
137
|
+
connection = connection_class.new(nil, double(:logger), master_connection, [read_connection_1], {read_connection_1 => 1}, config)
|
138
|
+
expect(master_connection).to receive(:begin_db_transaction)
|
139
|
+
expect(master_connection).to receive(:commit_db_transaction)
|
140
|
+
expect(master_connection).to receive(:select).with('Transaction SQL', nil)
|
141
|
+
expect(read_connection_1).to receive(:select).with('SQL 1', nil)
|
142
|
+
expect(read_connection_1).to receive(:select).with('SQL 2', nil)
|
142
143
|
|
143
144
|
SeamlessDatabasePool.use_persistent_read_connection do
|
144
145
|
connection.send(:select, 'SQL 1', nil)
|
@@ -152,81 +153,81 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
152
153
|
|
153
154
|
context "read connection methods" do
|
154
155
|
it "should proxy select methods to a read connection" do
|
155
|
-
pool_connection.
|
156
|
-
read_connection_1.
|
156
|
+
expect(pool_connection).to receive(:current_read_connection).and_return(read_connection_1)
|
157
|
+
expect(read_connection_1).to receive(:select).with('SQL').and_return(:retval)
|
157
158
|
pool_connection.send(:select, 'SQL').should == :retval
|
158
159
|
end
|
159
160
|
|
160
161
|
it "should proxy execute methods to a read connection" do
|
161
|
-
pool_connection.
|
162
|
-
read_connection_1.
|
162
|
+
expect(pool_connection).to receive(:current_read_connection).and_return(read_connection_1)
|
163
|
+
expect(read_connection_1).to receive(:execute).with('SQL').and_return(:retval)
|
163
164
|
pool_connection.execute('SQL').should == :retval
|
164
165
|
end
|
165
166
|
|
166
167
|
it "should proxy select_rows methods to a read connection" do
|
167
|
-
pool_connection.
|
168
|
-
read_connection_1.
|
168
|
+
expect(pool_connection).to receive(:current_read_connection).and_return(read_connection_1)
|
169
|
+
expect(read_connection_1).to receive(:select_rows).with('SQL').and_return(:retval)
|
169
170
|
pool_connection.select_rows('SQL').should == :retval
|
170
171
|
end
|
171
172
|
end
|
172
173
|
|
173
174
|
context "master connection methods" do
|
174
175
|
it "should proxy insert method to the master connection" do
|
175
|
-
master_connection.
|
176
|
+
expect(master_connection).to receive(:insert).with('SQL').and_return(:retval)
|
176
177
|
pool_connection.insert('SQL').should == :retval
|
177
178
|
end
|
178
179
|
|
179
180
|
it "should proxy update method to the master connection" do
|
180
|
-
master_connection.
|
181
|
+
expect(master_connection).to receive(:update).with('SQL').and_return(:retval)
|
181
182
|
pool_connection.update('SQL').should == :retval
|
182
183
|
end
|
183
184
|
|
184
185
|
it "should proxy columns method to the master connection" do
|
185
|
-
master_connection.
|
186
|
+
expect(master_connection).to receive(:columns).with(:table).and_return(:retval)
|
186
187
|
pool_connection.columns(:table).should == :retval
|
187
188
|
end
|
188
189
|
end
|
189
190
|
|
190
191
|
context "fork to all connections" do
|
191
192
|
it "should fork active? to all connections and return true if all are up" do
|
192
|
-
master_connection.
|
193
|
-
read_connection_1.
|
194
|
-
read_connection_2.
|
193
|
+
expect(master_connection).to receive(:active?).and_return(true)
|
194
|
+
expect(read_connection_1).to receive(:active?).and_return(true)
|
195
|
+
expect(read_connection_2).to receive(:active?).and_return(true)
|
195
196
|
pool_connection.active?.should == true
|
196
197
|
end
|
197
198
|
|
198
199
|
it "should fork active? to all connections and return false if one is down" do
|
199
|
-
master_connection.
|
200
|
-
read_connection_1.
|
201
|
-
read_connection_2.
|
200
|
+
expect(master_connection).to receive(:active?).and_return(true)
|
201
|
+
expect(read_connection_1).to receive(:active?).and_return(true)
|
202
|
+
expect(read_connection_2).to receive(:active?).and_return(false)
|
202
203
|
pool_connection.active?.should == false
|
203
204
|
end
|
204
205
|
|
205
206
|
it "should fork verify! to all connections" do
|
206
|
-
master_connection.
|
207
|
-
read_connection_1.
|
208
|
-
read_connection_2.
|
207
|
+
expect(master_connection).to receive(:verify!).with(5)
|
208
|
+
expect(read_connection_1).to receive(:verify!).with(5)
|
209
|
+
expect(read_connection_2).to receive(:verify!).with(5)
|
209
210
|
pool_connection.verify!(5)
|
210
211
|
end
|
211
212
|
|
212
213
|
it "should fork disconnect! to all connections" do
|
213
|
-
master_connection.
|
214
|
-
read_connection_1.
|
215
|
-
read_connection_2.
|
214
|
+
expect(master_connection).to receive(:disconnect!)
|
215
|
+
expect(read_connection_1).to receive(:disconnect!)
|
216
|
+
expect(read_connection_2).to receive(:disconnect!)
|
216
217
|
pool_connection.disconnect!
|
217
218
|
end
|
218
219
|
|
219
220
|
it "should fork reconnect! to all connections" do
|
220
|
-
master_connection.
|
221
|
-
read_connection_1.
|
222
|
-
read_connection_2.
|
221
|
+
expect(master_connection).to receive(:reconnect!)
|
222
|
+
expect(read_connection_1).to receive(:reconnect!)
|
223
|
+
expect(read_connection_2).to receive(:reconnect!)
|
223
224
|
pool_connection.reconnect!
|
224
225
|
end
|
225
226
|
|
226
227
|
it "should fork reset_runtime to all connections" do
|
227
|
-
master_connection.
|
228
|
-
read_connection_1.
|
229
|
-
read_connection_2.
|
228
|
+
expect(master_connection).to receive(:reset_runtime).and_return(1)
|
229
|
+
expect(read_connection_1).to receive(:reset_runtime).and_return(2)
|
230
|
+
expect(read_connection_2).to receive(:reset_runtime).and_return(3)
|
230
231
|
pool_connection.reset_runtime.should == 6
|
231
232
|
end
|
232
233
|
end
|
@@ -235,16 +236,17 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
235
236
|
it "should proxy requests to a connection" do
|
236
237
|
args = [:arg1, :arg2]
|
237
238
|
block = Proc.new{}
|
238
|
-
master_connection.
|
239
|
+
expect(master_connection).to receive(:select_value).with(*args, &block)
|
239
240
|
master_connection.should_not_receive(:active?)
|
240
241
|
master_connection.should_not_receive(:reconnect!)
|
241
242
|
pool_connection.send(:proxy_connection_method, master_connection, :select_value, :master, *args, &block)
|
242
243
|
end
|
243
244
|
|
244
245
|
it "should try to reconnect dead connections when they become available again" do
|
245
|
-
master_connection.stub(:select).and_raise("SQL ERROR")
|
246
|
-
master_connection.
|
247
|
-
master_connection.
|
246
|
+
master_connection.stub(:select).and_raise("SQL ERROR") # Rails 3, 4
|
247
|
+
master_connection.stub(:select_rows).and_raise("SQL ERROR") # Rails 5
|
248
|
+
expect(master_connection).to receive(:active?).and_return(false, false, true)
|
249
|
+
expect(master_connection).to receive(:reconnect!)
|
248
250
|
now = Time.now
|
249
251
|
lambda{pool_connection.select_value("SQL")}.should raise_error("SQL ERROR")
|
250
252
|
Time.stub(:now => now + 31)
|
@@ -254,8 +256,8 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
254
256
|
it "should not try to reconnect live connections" do
|
255
257
|
args = [:arg1, :arg2]
|
256
258
|
block = Proc.new{}
|
257
|
-
master_connection.
|
258
|
-
master_connection.
|
259
|
+
expect(master_connection).to receive(:select).with(*args, &block).twice.and_raise("SQL ERROR")
|
260
|
+
expect(master_connection).to receive(:active?).and_return(true)
|
259
261
|
master_connection.should_not_receive(:reconnect!)
|
260
262
|
lambda{pool_connection.send(:proxy_connection_method, master_connection, :select, :read, *args, &block)}.should raise_error("SQL ERROR")
|
261
263
|
end
|
@@ -263,7 +265,7 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
263
265
|
it "should not try to reconnect a connection during a retry" do
|
264
266
|
args = [:arg1, :arg2]
|
265
267
|
block = Proc.new{}
|
266
|
-
master_connection.
|
268
|
+
expect(master_connection).to receive(:select).with(*args, &block).and_raise("SQL ERROR")
|
267
269
|
master_connection.should_not_receive(:active?)
|
268
270
|
master_connection.should_not_receive(:reconnect!)
|
269
271
|
lambda{pool_connection.send(:proxy_connection_method, master_connection, :select, :retry, *args, &block)}.should raise_error("SQL ERROR")
|
@@ -271,35 +273,35 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
271
273
|
|
272
274
|
it "should try to execute a read statement again after a connection error" do
|
273
275
|
connection_error = ActiveRecord::ConnectionAdapters::SeamlessDatabasePoolAdapter::DatabaseConnectionError.new
|
274
|
-
pool_connection.
|
275
|
-
read_connection_1.
|
276
|
-
read_connection_1.
|
276
|
+
expect(pool_connection).to receive(:current_read_connection).and_return(read_connection_1)
|
277
|
+
expect(read_connection_1).to receive(:select).with('SQL').and_raise(connection_error)
|
278
|
+
expect(read_connection_1).to receive(:active?).and_return(true)
|
277
279
|
pool_connection.should_not_receive(:suppress_read_connection)
|
278
280
|
SeamlessDatabasePool.should_not_receive(:set_persistent_read_connection)
|
279
|
-
read_connection_1.
|
281
|
+
expect(read_connection_1).to receive(:select).with('SQL').and_return(:results)
|
280
282
|
pool_connection.send(:select, 'SQL').should == :results
|
281
283
|
end
|
282
284
|
|
283
285
|
it "should not try to execute a read statement again after a connection error if the master connection must be used" do
|
284
|
-
master_connection.
|
286
|
+
expect(master_connection).to receive(:select).with('SQL').and_raise("Fail")
|
285
287
|
pool_connection.use_master_connection do
|
286
288
|
lambda{pool_connection.send(:select, 'SQL')}.should raise_error("Fail")
|
287
289
|
end
|
288
290
|
end
|
289
291
|
|
290
292
|
it "should not try to execute a read statement again after a non-connection error" do
|
291
|
-
pool_connection.
|
292
|
-
pool_connection.
|
293
|
+
expect(pool_connection).to receive(:current_read_connection).and_return(read_connection_1)
|
294
|
+
expect(pool_connection).to receive(:proxy_connection_method).with(read_connection_1, :select, :read, 'SQL').and_raise("SQL Error")
|
293
295
|
lambda{pool_connection.send(:select, 'SQL')}.should raise_error("SQL Error")
|
294
296
|
end
|
295
297
|
|
296
298
|
it "should use a different connection on a retry if the original connection could not be reconnected" do
|
297
|
-
pool_connection.
|
298
|
-
read_connection_1.
|
299
|
-
read_connection_1.
|
300
|
-
pool_connection.
|
301
|
-
SeamlessDatabasePool.
|
302
|
-
read_connection_2.
|
299
|
+
expect(pool_connection).to receive(:current_read_connection).and_return(read_connection_1, read_connection_2)
|
300
|
+
expect(read_connection_1).to receive(:select).with('SQL').and_raise("Fail")
|
301
|
+
expect(read_connection_1).to receive(:active?).and_return(false)
|
302
|
+
expect(pool_connection).to receive(:suppress_read_connection).with(read_connection_1, 30)
|
303
|
+
expect(SeamlessDatabasePool).to receive(:set_persistent_read_connection).with(pool_connection, read_connection_2)
|
304
|
+
expect(read_connection_2).to receive(:select).with('SQL').and_return(:results)
|
303
305
|
pool_connection.send(:select, 'SQL').should == :results
|
304
306
|
end
|
305
307
|
|
@@ -322,8 +324,8 @@ describe "SeamlessDatabasePoolAdapter" do
|
|
322
324
|
pool_connection.suppress_read_connection(read_connection_1, 0.2)
|
323
325
|
pool_connection.available_read_connections.should_not include(read_connection_1)
|
324
326
|
sleep(0.3)
|
325
|
-
read_connection_1.
|
326
|
-
read_connection_1.
|
327
|
+
expect(read_connection_1).to receive(:reconnect!)
|
328
|
+
expect(read_connection_1).to receive(:active?).and_return(false)
|
327
329
|
pool_connection.available_read_connections.should_not include(read_connection_1)
|
328
330
|
end
|
329
331
|
|
data/spec/spec_helper.rb
CHANGED
@@ -11,3 +11,15 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'seamles
|
|
11
11
|
require File.expand_path(File.join(File.dirname(__FILE__), 'test_model'))
|
12
12
|
|
13
13
|
$LOAD_PATH << File.expand_path("../test_adapter", __FILE__)
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.run_all_when_everything_filtered = true
|
17
|
+
config.filter_run :focus
|
18
|
+
|
19
|
+
# Run specs in random order to surface order dependencies. If you find an
|
20
|
+
# order dependency and want to debug it, you can fix the order by providing
|
21
|
+
# the seed, which is printed after each run.
|
22
|
+
# --seed 1234
|
23
|
+
config.order = 'random'
|
24
|
+
config.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }
|
25
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seamless_database_pool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Durand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: jeweler
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: sqlite3
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,23 +80,28 @@ dependencies:
|
|
94
80
|
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
|
-
description:
|
98
|
-
|
83
|
+
description: Add support for master/slave database database clusters in ActiveRecord
|
84
|
+
to improve performance.
|
85
|
+
email:
|
86
|
+
- bbdurand@gmail.com
|
99
87
|
executables: []
|
100
88
|
extensions: []
|
101
|
-
extra_rdoc_files:
|
102
|
-
- MIT-LICENSE
|
103
|
-
- README.rdoc
|
89
|
+
extra_rdoc_files: []
|
104
90
|
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".travis.yml"
|
93
|
+
- HISTORY.txt
|
105
94
|
- MIT-LICENSE
|
106
95
|
- README.rdoc
|
107
96
|
- Rakefile
|
97
|
+
- VERSION
|
108
98
|
- lib/active_record/connection_adapters/seamless_database_pool_adapter.rb
|
109
99
|
- lib/seamless_database_pool.rb
|
110
100
|
- lib/seamless_database_pool/arel_compiler.rb
|
111
101
|
- lib/seamless_database_pool/connection_statistics.rb
|
112
102
|
- lib/seamless_database_pool/controller_filter.rb
|
113
103
|
- lib/seamless_database_pool/railtie.rb
|
104
|
+
- seamless_database_pool.gemspec
|
114
105
|
- spec/connection_adapters_spec.rb
|
115
106
|
- spec/connection_statistics_spec.rb
|
116
107
|
- spec/controller_filter_spec.rb
|
@@ -120,8 +111,9 @@ files:
|
|
120
111
|
- spec/spec_helper.rb
|
121
112
|
- spec/test_adapter/active_record/connection_adapters/read_only_adapter.rb
|
122
113
|
- spec/test_model.rb
|
123
|
-
homepage:
|
124
|
-
licenses:
|
114
|
+
homepage: https://github.com/bdurand/seamless_database_pool
|
115
|
+
licenses:
|
116
|
+
- MIT
|
125
117
|
metadata: {}
|
126
118
|
post_install_message:
|
127
119
|
rdoc_options: []
|
@@ -139,9 +131,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
131
|
version: '0'
|
140
132
|
requirements: []
|
141
133
|
rubyforge_project:
|
142
|
-
rubygems_version: 2.
|
134
|
+
rubygems_version: 2.4.5
|
143
135
|
signing_key:
|
144
136
|
specification_version: 4
|
145
137
|
summary: Add support for master/slave database clusters in ActiveRecord to improve
|
146
138
|
performance.
|
147
|
-
test_files:
|
139
|
+
test_files:
|
140
|
+
- spec/connection_adapters_spec.rb
|
141
|
+
- spec/connection_statistics_spec.rb
|
142
|
+
- spec/controller_filter_spec.rb
|
143
|
+
- spec/database.yml
|
144
|
+
- spec/seamless_database_pool_adapter_spec.rb
|
145
|
+
- spec/seamless_database_pool_spec.rb
|
146
|
+
- spec/spec_helper.rb
|
147
|
+
- spec/test_adapter/active_record/connection_adapters/read_only_adapter.rb
|
148
|
+
- spec/test_model.rb
|