replidog 1.0.0 → 1.1.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/CHANGELOG.md +8 -0
- data/lib/replidog/proxy.rb +5 -1
- data/lib/replidog/proxy_handler.rb +21 -14
- data/lib/replidog/version.rb +1 -1
- data/replidog.gemspec +1 -0
- data/spec/replidog/model_spec.rb +48 -12
- data/spec/replidog/proxy_spec.rb +2 -2
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb2c9700cd4d59f081d362c08eac02be9943b8cc
|
4
|
+
data.tar.gz: 33f1819e45ec2d9ebd7bcdf7a76186b552fe72a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b0ea44389e81fb76b256d77658bf1557f7198308f23a7735b012ff3405d99496f8d52ad7a166c4f235fe9338cd338cc4c2ed07c5f1b1a79faafca5c6259ce7c
|
7
|
+
data.tar.gz: af3bf2d9607c49327c52878fae02bde825db827124d702f96934dd1561866aabaf7bb20bbec95146383e7151cf7b239a15080f802175043bab53275f8531a715
|
data/CHANGELOG.md
ADDED
data/lib/replidog/proxy.rb
CHANGED
@@ -14,6 +14,7 @@ module Replidog
|
|
14
14
|
def initialize(handler, configuration)
|
15
15
|
@handler = handler
|
16
16
|
@configuration = configuration
|
17
|
+
@lock = Mutex.new
|
17
18
|
end
|
18
19
|
|
19
20
|
def current_model
|
@@ -58,6 +59,7 @@ module Replidog
|
|
58
59
|
|
59
60
|
def clear_all_slave_connections!
|
60
61
|
slave_connection_pool_table.each_value do |pool|
|
62
|
+
pool.automatic_reconnect = false
|
61
63
|
pool.disconnect!
|
62
64
|
end
|
63
65
|
end
|
@@ -149,7 +151,9 @@ module Replidog
|
|
149
151
|
end
|
150
152
|
|
151
153
|
def slave_connection_index
|
152
|
-
|
154
|
+
@lock.synchronize do
|
155
|
+
index.tap { increment_slave_connection_index }
|
156
|
+
end
|
153
157
|
end
|
154
158
|
|
155
159
|
def increment_slave_connection_index
|
@@ -1,29 +1,36 @@
|
|
1
|
+
require "concurrent/map"
|
2
|
+
|
1
3
|
module Replidog
|
2
4
|
class ProxyHandler
|
3
5
|
def initialize
|
4
|
-
@proxies =
|
5
|
-
@class_to_proxy =
|
6
|
+
@proxies = Concurrent::Map.new(initial_capacity: 2)
|
7
|
+
@class_to_proxy = Concurrent::Map.new(initial_capacity: 2)
|
6
8
|
end
|
7
9
|
|
8
10
|
def establish_connection(configuration, klass)
|
9
|
-
@
|
10
|
-
|
11
|
+
@class_to_proxy.clear
|
12
|
+
raise RuntimeError, "Anonymous class is not allowed." unless klass.name
|
13
|
+
@proxies[klass.name] = Proxy.new(self, configuration)
|
11
14
|
end
|
12
15
|
|
13
16
|
def retrieve_proxy(klass)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
@class_to_proxy[klass.name] ||=
|
18
|
+
begin
|
19
|
+
until proxy = @proxies[klass.name]
|
20
|
+
klass = klass.superclass
|
21
|
+
break unless klass <= ActiveRecord::Base
|
22
|
+
end
|
23
|
+
|
24
|
+
@class_to_proxy[klass.name] = proxy
|
25
|
+
end
|
18
26
|
end
|
19
27
|
|
20
28
|
def remove_connection(klass)
|
21
|
-
proxy = @
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
proxy.configuration.config
|
29
|
+
if proxy = @proxies.delete(klass.name)
|
30
|
+
@class_to_proxy.clear
|
31
|
+
proxy.clear_all_slave_connections!
|
32
|
+
proxy.configuration.config
|
33
|
+
end
|
27
34
|
end
|
28
35
|
|
29
36
|
def clear_active_slave_connections!
|
data/lib/replidog/version.rb
CHANGED
data/replidog.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_dependency "activerecord", '>= 3.2.0'
|
21
21
|
spec.add_dependency "activesupport", '>= 3.2.0'
|
22
|
+
spec.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
|
22
23
|
spec.add_development_dependency 'appraisal'
|
23
24
|
spec.add_development_dependency "bundler", "~> 1.7"
|
24
25
|
spec.add_development_dependency "coffee-rails", ">= 3.2.0"
|
data/spec/replidog/model_spec.rb
CHANGED
@@ -10,6 +10,11 @@ describe Replidog::Model do
|
|
10
10
|
User.using(:slave).first
|
11
11
|
end
|
12
12
|
|
13
|
+
before do
|
14
|
+
ActiveRecord::Base.establish_connection
|
15
|
+
UserTable.establish_connection :test_user
|
16
|
+
end
|
17
|
+
|
13
18
|
describe ".extended" do
|
14
19
|
it "shares the same proxy_handler" do
|
15
20
|
expect(Recipe.proxy_handler).to eq User.proxy_handler
|
@@ -79,18 +84,49 @@ describe Replidog::Model do
|
|
79
84
|
expect(Recipe.first).to be_nil
|
80
85
|
end
|
81
86
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
87
|
+
context "with single thread" do
|
88
|
+
it "selects replications by roundrobin order" do
|
89
|
+
Recipe.using(:slave1).create(title: "test")
|
90
|
+
Recipe.connection.index = 0
|
91
|
+
expect(Recipe.first).not_to be_nil
|
92
|
+
expect(Recipe.first).to be_nil
|
93
|
+
expect(Recipe.first).to be_nil
|
94
|
+
expect(Recipe.first).not_to be_nil
|
95
|
+
expect(Recipe.first).to be_nil
|
96
|
+
expect(Recipe.first).to be_nil
|
97
|
+
expect(Recipe.first).not_to be_nil
|
98
|
+
expect(Recipe.first).to be_nil
|
99
|
+
expect(Recipe.first).to be_nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "with multi thread" do
|
104
|
+
it "selects replications by roundrobin order" do
|
105
|
+
Recipe.using(:slave1).create(title: "test")
|
106
|
+
# Clear connection pool
|
107
|
+
ActiveRecord::Base.establish_connection
|
108
|
+
Recipe.connection.index = 0
|
109
|
+
|
110
|
+
recipes = []
|
111
|
+
pool_size = 5
|
112
|
+
iteration_size = 2
|
113
|
+
slave_size = 3
|
114
|
+
num_of_trials = pool_size * iteration_size
|
115
|
+
|
116
|
+
threads = []
|
117
|
+
|
118
|
+
pool_size.times do |i|
|
119
|
+
threads << Thread.new do
|
120
|
+
iteration_size.times do
|
121
|
+
recipes << Recipe.first
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
threads.each(&:join)
|
127
|
+
|
128
|
+
expect(recipes.compact.size).to eq (num_of_trials + slave_size - 1) / slave_size
|
129
|
+
end
|
94
130
|
end
|
95
131
|
end
|
96
132
|
end
|
data/spec/replidog/proxy_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: replidog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manabu Ejima
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -38,6 +38,26 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: concurrent-ruby
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.0.2
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.0'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.0.2
|
41
61
|
- !ruby/object:Gem::Dependency
|
42
62
|
name: appraisal
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -271,6 +291,7 @@ extra_rdoc_files: []
|
|
271
291
|
files:
|
272
292
|
- ".gitignore"
|
273
293
|
- Appraisals
|
294
|
+
- CHANGELOG.md
|
274
295
|
- Gemfile
|
275
296
|
- LICENSE.txt
|
276
297
|
- README.md
|
@@ -345,7 +366,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
345
366
|
version: '0'
|
346
367
|
requirements: []
|
347
368
|
rubyforge_project:
|
348
|
-
rubygems_version: 2.
|
369
|
+
rubygems_version: 2.5.1
|
349
370
|
signing_key:
|
350
371
|
specification_version: 4
|
351
372
|
summary: master-slave replication helper for ActiveRecord
|