replidog 1.0.0 → 1.1.0

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