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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44af9edc1ca7b64ca4c802cec1e865f31318533b
4
- data.tar.gz: 29a251aad399f14c85813e655dc184b46ecab204
3
+ metadata.gz: cb2c9700cd4d59f081d362c08eac02be9943b8cc
4
+ data.tar.gz: 33f1819e45ec2d9ebd7bcdf7a76186b552fe72a5
5
5
  SHA512:
6
- metadata.gz: e8a1858c3e07cbe87e516d80705e448d6afc508a1b5e3c0bc6dc30ebade7cebcb99c8bbe0e03d9465b2b8cdc6247ea08b93d5bcae62633d938530b8808820be0
7
- data.tar.gz: 09914f2faa17a58fc50f5428efea7b4acc38246da64c57fa3280610c301a20b2e75f255578e5cc665f88dce212157a2c4aba8ff59ccda4a8521c48d3f12a123f
6
+ metadata.gz: 2b0ea44389e81fb76b256d77658bf1557f7198308f23a7735b012ff3405d99496f8d52ad7a166c4f235fe9338cd338cc4c2ed07c5f1b1a79faafca5c6259ce7c
7
+ data.tar.gz: af3bf2d9607c49327c52878fae02bde825db827124d702f96934dd1561866aabaf7bb20bbec95146383e7151cf7b239a15080f802175043bab53275f8531a715
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ ## 1.1.0
2
+ - Support multithread
3
+
4
+ ## 1.0.0
5
+ - Support Rails 5.0
6
+
7
+ ## 0.1.0
8
+ - First release
@@ -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
- index.tap { increment_slave_connection_index }
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
- @proxies[configuration] ||= Proxy.new(self, configuration)
10
- @class_to_proxy[klass.name] ||= @proxies[configuration]
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
- proxy = @class_to_proxy[klass.name]
15
- return proxy if proxy
16
- return nil if ActiveRecord::Base == klass
17
- retrieve_proxy(klass.superclass)
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 = @class_to_proxy.delete(klass.name)
22
- return nil unless proxy
23
-
24
- @proxies.delete(proxy.configuration)
25
- proxy.clear_all_slave_connections!
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!
@@ -1,3 +1,3 @@
1
1
  module Replidog
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
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"
@@ -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
- it "selects replications by roundrobin order" do
83
- Recipe.using(:slave1).create(title: "test")
84
- Recipe.connection.index = 0
85
- expect(Recipe.first).not_to be_nil
86
- expect(Recipe.first).to be_nil
87
- expect(Recipe.first).to be_nil
88
- expect(Recipe.first).not_to be_nil
89
- expect(Recipe.first).to be_nil
90
- expect(Recipe.first).to be_nil
91
- expect(Recipe.first).not_to be_nil
92
- expect(Recipe.first).to be_nil
93
- expect(Recipe.first).to be_nil
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
@@ -2,8 +2,8 @@ require "spec_helper"
2
2
 
3
3
  describe Replidog::Proxy do
4
4
  before do
5
- # call establish_connection
6
- UserTable
5
+ ActiveRecord::Base.establish_connection
6
+ UserTable.establish_connection :test_user
7
7
  end
8
8
 
9
9
  describe "#enable_query_cache!" do
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.0.0
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-07-07 00:00:00.000000000 Z
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.4.5.1
369
+ rubygems_version: 2.5.1
349
370
  signing_key:
350
371
  specification_version: 4
351
372
  summary: master-slave replication helper for ActiveRecord