activerecord-turntable 2.1.1 → 2.2.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 +18 -0
- data/README.md +6 -6
- data/lib/active_record/turntable/algorithm.rb +1 -0
- data/lib/active_record/turntable/algorithm/modulo_algorithm.rb +14 -0
- data/lib/active_record/turntable/cluster.rb +5 -2
- data/lib/active_record/turntable/mixer.rb +1 -1
- data/lib/active_record/turntable/seq_shard.rb +7 -0
- data/lib/active_record/turntable/shard.rb +6 -1
- data/lib/active_record/turntable/version.rb +1 -1
- data/spec/active_record/turntable/algorithm/modulo_algorithm_spec.rb +35 -0
- data/spec/active_record/turntable/algorithm_spec.rb +15 -0
- data/spec/active_record/turntable/cluster_spec.rb +9 -0
- data/spec/config/turntable.yml +22 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b5ef39b2f1a9eaa4b861f4e7ac57aabc2fffa21
|
4
|
+
data.tar.gz: 9cf6ae9ab38f0ebc8268a63fe188ed354b14deb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26b6729a9cfe48c15982a3c23b748a2cc23746a79a16cc6a522f9e84dab6095ad156b7d193d9c324c5a76b4ccdcbd5b295ef95ff306dbf396819bfee6d473502
|
7
|
+
data.tar.gz: b96d8f0a07f38f527e6298c48fa7017fb6ffb3596c78410f4a0b0ebb57c1c29446aec04b27d98ccc5c1a34aaa9f464460c6a87c58eb687f18690d679996896f0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## activerecord-turntable 2.2.0 ##
|
2
|
+
|
3
|
+
### Features
|
4
|
+
|
5
|
+
* Add `modulo` algorithm (thx tatsuma)
|
6
|
+
|
7
|
+
### Improvements
|
8
|
+
|
9
|
+
* Add err detail to Building Fader exception log (thx tatsuma)
|
10
|
+
|
11
|
+
### Bugfixes
|
12
|
+
|
13
|
+
* Fix building cluster with mysql sequencer (fixes #25) (thx tatsuma)
|
14
|
+
|
15
|
+
### Documentation
|
16
|
+
|
17
|
+
* Fix seqeucner example (thx akicho8, tatsuma)
|
18
|
+
|
1
19
|
## activerecord-turntable 2.1.1 ##
|
2
20
|
|
3
21
|
### Bugfixes
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Currently supports mysql only.
|
|
22
22
|
Add to Gemfile:
|
23
23
|
|
24
24
|
```ruby
|
25
|
-
gem 'activerecord-turntable', '~> 2.
|
25
|
+
gem 'activerecord-turntable', '~> 2.1.1'
|
26
26
|
```
|
27
27
|
|
28
28
|
Run a bundle install:
|
@@ -90,14 +90,14 @@ Edit turntable.yml and database.yml. See below example config.
|
|
90
90
|
development:
|
91
91
|
clusters:
|
92
92
|
user_cluster: # <-- cluster name
|
93
|
-
algorithm: range_bsearch # <-- `range` or `
|
93
|
+
algorithm: range_bsearch # <-- `range`, `range_bsearch` or `modulo`
|
94
94
|
seq:
|
95
95
|
user_seq: # <-- sequencer name
|
96
96
|
seq_type: mysql # <-- sequencer type
|
97
97
|
connection: user_seq_1 # <-- sequencer database connection setting
|
98
98
|
shards:
|
99
99
|
- connection: user_shard_1 # <-- shard name
|
100
|
-
less_than: 100 # <-- shard range(like mysql partitioning)
|
100
|
+
less_than: 100 # <-- shard range(like mysql partitioning) If you are using a modulo algorithm, it doesn't need it.
|
101
101
|
- connection: user_shard_2
|
102
102
|
less_than: 200
|
103
103
|
- connection: user_shard_3
|
@@ -178,13 +178,13 @@ Add turntable [shard_key_name] to the model class:
|
|
178
178
|
```ruby
|
179
179
|
class User < ActiveRecord::Base
|
180
180
|
turntable :user_cluster, :id
|
181
|
-
sequencer
|
181
|
+
sequencer :user_seq
|
182
182
|
has_one :status
|
183
183
|
end
|
184
184
|
|
185
185
|
class Status < ActiveRecord::Base
|
186
186
|
turntable :user_cluster, :user_id
|
187
|
-
sequencer
|
187
|
+
sequencer :user_seq
|
188
188
|
belongs_to :user
|
189
189
|
end
|
190
190
|
```
|
@@ -296,7 +296,7 @@ Next, add sequencer definition to the model:
|
|
296
296
|
```ruby
|
297
297
|
class User < ActiveRecord::Base
|
298
298
|
turntable :id
|
299
|
-
sequencer :
|
299
|
+
sequencer :user_seq # <-- this line enables sequencer module
|
300
300
|
has_one :status
|
301
301
|
end
|
302
302
|
```
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module ActiveRecord::Turntable::Algorithm
|
3
|
+
class ModuloAlgorithm < Base
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def calculate(key)
|
9
|
+
@config["shards"][key % @config["shards"].size]["connection"]
|
10
|
+
rescue
|
11
|
+
raise ActiveRecord::Turntable::CannotSpecifyShardError, "cannot specify shard for key:#{key}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -14,8 +14,11 @@ module ActiveRecord::Turntable
|
|
14
14
|
@shards = {}.with_indifferent_access
|
15
15
|
|
16
16
|
# setup sequencer
|
17
|
-
|
18
|
-
|
17
|
+
seq = (@options[:seq] || @config[:seq])
|
18
|
+
if seq
|
19
|
+
if seq.values.size > 0 && seq.values.first["seq_type"] == "mysql"
|
20
|
+
@seq_shard = SeqShard.new(seq.values.first)
|
21
|
+
end
|
19
22
|
end
|
20
23
|
|
21
24
|
# setup shards
|
@@ -48,7 +48,7 @@ module ActiveRecord::Turntable
|
|
48
48
|
method, query, *args, &block)
|
49
49
|
end
|
50
50
|
rescue Exception => err
|
51
|
-
logger.warn { "[ActiveRecord::Turntable] Error on Building Fader: #{binded_query}, on_method: #{method_name}" }
|
51
|
+
logger.warn { "[ActiveRecord::Turntable] Error on Building Fader: #{binded_query}, on_method: #{method_name}, err: #{err}" }
|
52
52
|
raise err
|
53
53
|
end
|
54
54
|
|
@@ -2,6 +2,13 @@ module ActiveRecord::Turntable
|
|
2
2
|
class SeqShard < Shard
|
3
3
|
private
|
4
4
|
|
5
|
+
def create_connection_class
|
6
|
+
klass = get_or_set_connection_class
|
7
|
+
klass.remove_connection
|
8
|
+
klass.establish_connection ActiveRecord::Base.connection_pool.spec.config[:seq][name].with_indifferent_access
|
9
|
+
klass
|
10
|
+
end
|
11
|
+
|
5
12
|
def retrieve_connection_pool
|
6
13
|
ActiveRecord::Base.turntable_connections[name] ||=
|
7
14
|
begin
|
@@ -30,7 +30,7 @@ module ActiveRecord::Turntable
|
|
30
30
|
@connection_klass ||= create_connection_class
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def get_or_set_connection_class
|
34
34
|
if Connections.const_defined?(name.classify)
|
35
35
|
klass = Connections.const_get(name.classify)
|
36
36
|
else
|
@@ -38,6 +38,11 @@ module ActiveRecord::Turntable
|
|
38
38
|
Connections.const_set(name.classify, klass)
|
39
39
|
klass.abstract_class = true
|
40
40
|
end
|
41
|
+
klass
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_connection_class
|
45
|
+
klass = get_or_set_connection_class
|
41
46
|
klass.remove_connection
|
42
47
|
klass.establish_connection ActiveRecord::Base.connection_pool.spec.config[:shards][name].with_indifferent_access
|
43
48
|
klass
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveRecord::Turntable::Algorithm::ModuloAlgorithm do
|
4
|
+
before(:all) do
|
5
|
+
reload_turntable!(File.join(File.dirname(__FILE__), "../../../config/turntable.yml"))
|
6
|
+
end
|
7
|
+
|
8
|
+
context "When initialized" do
|
9
|
+
before do
|
10
|
+
@alg = ActiveRecord::Turntable::Algorithm::ModuloAlgorithm.new(ActiveRecord::Base.turntable_config[:clusters][:mod_cluster])
|
11
|
+
end
|
12
|
+
|
13
|
+
context "#calculate with 1" do
|
14
|
+
subject { @alg.calculate(1) }
|
15
|
+
it { is_expected.to eq(ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][1][:connection]) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context "#calculate with 3" do
|
19
|
+
subject { @alg.calculate(3) }
|
20
|
+
it { is_expected.to eq(ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][3][:connection]) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "#calculate with 5" do
|
24
|
+
subject { @alg.calculate(5) }
|
25
|
+
it { is_expected.to eq(ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][0][:connection]) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "#calculate with a value that is not a number" do
|
29
|
+
it "raises ActiveRecord::Turntable::CannotSpecifyShardError" do
|
30
|
+
expect { @alg.calculate('a') }.to raise_error(ActiveRecord::Turntable::CannotSpecifyShardError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -82,4 +82,19 @@ describe ActiveRecord::Turntable::Algorithm do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
describe ActiveRecord::Turntable::Algorithm::ModuloAlgorithm do
|
87
|
+
let(:algorithm) { ActiveRecord::Turntable::Algorithm::ModuloAlgorithm.new(ActiveRecord::Base.turntable_config[:clusters][:mod_cluster]) }
|
88
|
+
context "#calculate" do
|
89
|
+
it "called with 1 return user_shard_2" do
|
90
|
+
expect(algorithm.calculate(1)).to eq("user_shard_2")
|
91
|
+
end
|
92
|
+
it "called with 3 return user_shard_2" do
|
93
|
+
expect(algorithm.calculate(3)).to eq("user_shard_2")
|
94
|
+
end
|
95
|
+
it "called with 5 return user_shard_1" do
|
96
|
+
expect(algorithm.calculate(5)).to eq("user_shard_1")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
85
100
|
end
|
@@ -11,6 +11,8 @@ describe ActiveRecord::Turntable::Cluster do
|
|
11
11
|
end
|
12
12
|
let(:cluster_config) { ActiveRecord::Base.turntable_config[:clusters][:user_cluster] }
|
13
13
|
let(:cluster) { ActiveRecord::Turntable::Cluster.new(cluster_config) }
|
14
|
+
let(:mysql_mod_cluster_config) { ActiveRecord::Base.turntable_config[:clusters][:mysql_mod_cluster] }
|
15
|
+
let(:mysql_mod_cluster) { ActiveRecord::Turntable::Cluster.new(mysql_mod_cluster_config) }
|
14
16
|
let(:in_range_shard_key_value) { cluster_config[:shards].last[:less_than] - 1 }
|
15
17
|
let(:out_of_range_shard_key_value) { cluster_config[:shards].last[:less_than] }
|
16
18
|
|
@@ -20,6 +22,13 @@ describe ActiveRecord::Turntable::Cluster do
|
|
20
22
|
its(:shards) { should have(3).items }
|
21
23
|
end
|
22
24
|
|
25
|
+
context "When initialized mysql sequencer type cluster" do
|
26
|
+
subject { mysql_mod_cluster }
|
27
|
+
|
28
|
+
its(:shards) { should have(2).items }
|
29
|
+
its(:seq) { is_expected.not_to be nil }
|
30
|
+
end
|
31
|
+
|
23
32
|
describe "#shard_for" do
|
24
33
|
subject { cluster.shard_for(value) }
|
25
34
|
|
data/spec/config/turntable.yml
CHANGED
@@ -32,3 +32,25 @@ test:
|
|
32
32
|
less_than: 80000
|
33
33
|
- connection: user_shard_6
|
34
34
|
less_than: 10000000
|
35
|
+
mod_cluster:
|
36
|
+
algorithm: modulo
|
37
|
+
seq:
|
38
|
+
user_seq:
|
39
|
+
connection: turntable_user_seq_test
|
40
|
+
shards:
|
41
|
+
- connection: user_shard_1
|
42
|
+
- connection: user_shard_2
|
43
|
+
- connection: user_shard_1
|
44
|
+
- connection: user_shard_2
|
45
|
+
- connection: user_shard_3
|
46
|
+
mysql_mod_cluster:
|
47
|
+
algorithm: modulo
|
48
|
+
seq:
|
49
|
+
user_seq:
|
50
|
+
seq_type: mysql
|
51
|
+
connection: user_seq
|
52
|
+
shards:
|
53
|
+
- connection: user_shard_1
|
54
|
+
- connection: user_shard_2
|
55
|
+
- connection: user_shard_2
|
56
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-turntable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gussan
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-05-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -364,6 +364,7 @@ files:
|
|
364
364
|
- lib/active_record/turntable/algorithm.rb
|
365
365
|
- lib/active_record/turntable/algorithm/.gitkeep
|
366
366
|
- lib/active_record/turntable/algorithm/base.rb
|
367
|
+
- lib/active_record/turntable/algorithm/modulo_algorithm.rb
|
367
368
|
- lib/active_record/turntable/algorithm/range_algorithm.rb
|
368
369
|
- lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb
|
369
370
|
- lib/active_record/turntable/base.rb
|
@@ -412,6 +413,7 @@ files:
|
|
412
413
|
- spec/active_record/turntable/active_record_ext/migration_spec.rb
|
413
414
|
- spec/active_record/turntable/active_record_ext/persistence_spec.rb
|
414
415
|
- spec/active_record/turntable/active_record_ext/test_fixtures_spec.rb
|
416
|
+
- spec/active_record/turntable/algorithm/modulo_algorithm_spec.rb
|
415
417
|
- spec/active_record/turntable/algorithm/range_algorithm_spec.rb
|
416
418
|
- spec/active_record/turntable/algorithm/range_bsearch_algorithm_spec.rb
|
417
419
|
- spec/active_record/turntable/algorithm_spec.rb
|
@@ -482,6 +484,7 @@ test_files:
|
|
482
484
|
- spec/active_record/turntable/active_record_ext/migration_spec.rb
|
483
485
|
- spec/active_record/turntable/active_record_ext/persistence_spec.rb
|
484
486
|
- spec/active_record/turntable/active_record_ext/test_fixtures_spec.rb
|
487
|
+
- spec/active_record/turntable/algorithm/modulo_algorithm_spec.rb
|
485
488
|
- spec/active_record/turntable/algorithm/range_algorithm_spec.rb
|
486
489
|
- spec/active_record/turntable/algorithm/range_bsearch_algorithm_spec.rb
|
487
490
|
- spec/active_record/turntable/algorithm_spec.rb
|