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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a4bd6cbf61673b4f11bba18e22ff888a694f09a
4
- data.tar.gz: b94e9d04efa41f8b58f5b65bdcc51bd4cb2a890c
3
+ metadata.gz: 8b5ef39b2f1a9eaa4b861f4e7ac57aabc2fffa21
4
+ data.tar.gz: 9cf6ae9ab38f0ebc8268a63fe188ed354b14deb5
5
5
  SHA512:
6
- metadata.gz: 4c41774f64e47dde724ecd71b6eabe913c165d40ed159d73b867e0447ae64313437f0db4a4dcb98fb0e85f467ba3985b8a1974c6c97b558a9b793f115e093071
7
- data.tar.gz: 63184562e69d48c2b2ae73b70878d1b01e850c1caf5ff11fd7a21ebe3c5e157b12f4a84e79da4cb94b198fa82193aa86328f7b493078aaf5ac7644c9f59345c5
6
+ metadata.gz: 26b6729a9cfe48c15982a3c23b748a2cc23746a79a16cc6a522f9e84dab6095ad156b7d193d9c324c5a76b4ccdcbd5b295ef95ff306dbf396819bfee6d473502
7
+ data.tar.gz: b96d8f0a07f38f527e6298c48fa7017fb6ffb3596c78410f4a0b0ebb57c1c29446aec04b27d98ccc5c1a34aaa9f464460c6a87c58eb687f18690d679996896f0
@@ -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.0.0'
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 `range_bsearch`
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 :users_seq # <-- this line enables sequencer module
299
+ sequencer :user_seq # <-- this line enables sequencer module
300
300
  has_one :status
301
301
  end
302
302
  ```
@@ -6,6 +6,7 @@ module ActiveRecord::Turntable
6
6
  autoload :Base
7
7
  autoload :RangeAlgorithm
8
8
  autoload :RangeBsearchAlgorithm
9
+ autoload :ModuloAlgorithm
9
10
  end
10
11
  end
11
12
  end
@@ -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
- if (seq = (@options[:seq] || @config[:seq])) && seq[:type] == :mysql
18
- @seq_shard = SeqShard.new(seq)
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 create_connection_class
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
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Turntable
3
- VERSION = "2.1.1"
3
+ VERSION = "2.2.0"
4
4
  end
5
5
  end
@@ -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
 
@@ -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.1.1
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-01-26 00:00:00.000000000 Z
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