ar-octopus 0.9.0 → 0.9.1
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/.gitignore +1 -0
- data/.travis.yml +10 -2
- data/Appraisals +4 -0
- data/README.mkdn +1 -1
- data/gemfiles/rails51.gemfile +7 -0
- data/lib/octopus.rb +11 -6
- data/lib/octopus/collection_association.rb +9 -3
- data/lib/octopus/finder_methods.rb +1 -1
- data/lib/octopus/load_balancing/round_robin.rb +1 -0
- data/lib/octopus/log_subscriber.rb +6 -2
- data/lib/octopus/migration.rb +25 -9
- data/lib/octopus/model.rb +17 -25
- data/lib/octopus/proxy.rb +78 -279
- data/lib/octopus/proxy_config.rb +252 -0
- data/lib/octopus/relation_proxy.rb +7 -1
- data/lib/octopus/scope_proxy.rb +1 -1
- data/lib/octopus/shard_tracking.rb +2 -1
- data/lib/octopus/version.rb +1 -1
- data/spec/migrations/10_create_users_using_replication.rb +1 -1
- data/spec/migrations/11_add_field_in_all_slaves.rb +1 -1
- data/spec/migrations/12_create_users_using_block.rb +1 -1
- data/spec/migrations/13_create_users_using_block_and_using.rb +1 -1
- data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +1 -1
- data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +1 -1
- data/spec/migrations/1_create_users_on_master.rb +1 -1
- data/spec/migrations/2_create_users_on_canada.rb +1 -1
- data/spec/migrations/3_create_users_on_both_shards.rb +1 -1
- data/spec/migrations/4_create_users_on_shards_of_a_group.rb +1 -1
- data/spec/migrations/5_create_users_on_multiples_groups.rb +1 -1
- data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +1 -1
- data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +1 -1
- data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +1 -1
- data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +1 -1
- data/spec/octopus/association_shard_tracking_spec.rb +15 -15
- data/spec/octopus/load_balancing/round_robin_spec.rb +15 -0
- data/spec/octopus/log_subscriber_spec.rb +1 -1
- data/spec/octopus/model_spec.rb +34 -5
- data/spec/octopus/octopus_spec.rb +1 -1
- data/spec/octopus/proxy_spec.rb +16 -38
- data/spec/octopus/relation_proxy_spec.rb +4 -0
- data/spec/octopus/replication_spec.rb +5 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/octopus_helper.rb +1 -2
- data/spec/tasks/octopus.rake_spec.rb +2 -4
- metadata +7 -6
- data/.ruby-version +0 -1
- data/init.rb +0 -1
- data/rails/init.rb +0 -1
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octopus::LoadBalancing::RoundRobin do
|
4
|
+
it "raises an error when no shards are given" do
|
5
|
+
expect do
|
6
|
+
Octopus::LoadBalancing::RoundRobin.new([])
|
7
|
+
end.to raise_error Octopus::Exception
|
8
|
+
end
|
9
|
+
|
10
|
+
it "does not raise an error if slaves given" do
|
11
|
+
expect do
|
12
|
+
Octopus::LoadBalancing::RoundRobin.new([:stub])
|
13
|
+
end.to_not raise_error Octopus::Exception
|
14
|
+
end
|
15
|
+
end
|
@@ -9,7 +9,7 @@ describe Octopus::LogSubscriber, :shards => [:canada] do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
after :each do
|
12
|
-
ActiveRecord::Base.logger =
|
12
|
+
ActiveRecord::Base.logger = Logger.new(File.open('database.log', 'a'))
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'should add to the default logger the shard name the query was sent to' do
|
data/spec/octopus/model_spec.rb
CHANGED
@@ -90,7 +90,7 @@ describe Octopus::Model do
|
|
90
90
|
Octopus.using(:canada) do
|
91
91
|
fail 'Some Exception'
|
92
92
|
end
|
93
|
-
end.to raise_error
|
93
|
+
end.to raise_error(RuntimeError)
|
94
94
|
|
95
95
|
expect(ActiveRecord::Base.connection.current_shard).to eq(:master)
|
96
96
|
end
|
@@ -103,7 +103,7 @@ describe Octopus::Model do
|
|
103
103
|
Octopus.using(:canada) do
|
104
104
|
fail 'Some Exception'
|
105
105
|
end
|
106
|
-
end.to raise_error
|
106
|
+
end.to raise_error(RuntimeError)
|
107
107
|
|
108
108
|
expect(ActiveRecord::Base.connection.current_shard).to eq(:brazil)
|
109
109
|
Octopus.config[:master_shard] = nil
|
@@ -476,6 +476,34 @@ describe Octopus::Model do
|
|
476
476
|
expect(User.using(:master).count).to eq(1)
|
477
477
|
end
|
478
478
|
|
479
|
+
describe "#finder methods" do
|
480
|
+
before(:each) do
|
481
|
+
@user1 = User.using(:brazil).create!(:name => 'User1')
|
482
|
+
@user2 = User.using(:brazil).create!(:name => 'User2')
|
483
|
+
@user3 = User.using(:brazil).create!(:name => 'User3')
|
484
|
+
end
|
485
|
+
|
486
|
+
it "#find_each should work" do
|
487
|
+
result_array = []
|
488
|
+
|
489
|
+
User.using(:brazil).where("name is not NULL").find_each do |user|
|
490
|
+
result_array << user
|
491
|
+
end
|
492
|
+
|
493
|
+
expect(result_array).to eq([@user1, @user2, @user3])
|
494
|
+
end
|
495
|
+
|
496
|
+
it "#find_in_batches, should work" do
|
497
|
+
result_array = []
|
498
|
+
|
499
|
+
User.using(:brazil).where("name is not NULL").find_in_batches(batch_size: 1) do |user|
|
500
|
+
result_array << user
|
501
|
+
end
|
502
|
+
|
503
|
+
expect(result_array).to eq([[@user1], [@user2], [@user3]])
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
479
507
|
describe 'deleting a record' do
|
480
508
|
before(:each) do
|
481
509
|
@user = User.using(:brazil).create!(:name => 'User1')
|
@@ -665,20 +693,21 @@ describe Octopus::Model do
|
|
665
693
|
it 'should work correctly when using validations' do
|
666
694
|
@key = Keyboard.create!(:name => 'Key')
|
667
695
|
expect { Keyboard.using(:brazil).create!(:name => 'Key') }.not_to raise_error
|
668
|
-
expect { Keyboard.create!(:name => 'Key') }.to raise_error
|
696
|
+
expect { Keyboard.create!(:name => 'Key') }.to raise_error(ActiveRecord::RecordInvalid)
|
669
697
|
end
|
670
698
|
|
671
699
|
it 'should work correctly when using validations with using syntax' do
|
672
700
|
@key = Keyboard.using(:brazil).create!(:name => 'Key')
|
673
701
|
expect { Keyboard.create!(:name => 'Key') }.not_to raise_error
|
674
|
-
expect { Keyboard.using(:brazil).create!(:name => 'Key') }
|
702
|
+
expect { Keyboard.using(:brazil).create!(:name => 'Key') }
|
703
|
+
.to raise_error(ActiveRecord::RecordInvalid)
|
675
704
|
end
|
676
705
|
end
|
677
706
|
|
678
707
|
describe '#replicated_model method' do
|
679
708
|
it 'should be replicated' do
|
680
709
|
OctopusHelper.using_environment :production_replicated do
|
681
|
-
expect(ActiveRecord::Base.connection_proxy.
|
710
|
+
expect(ActiveRecord::Base.connection_proxy.replicated).to be true
|
682
711
|
end
|
683
712
|
end
|
684
713
|
|
@@ -37,7 +37,7 @@ describe Octopus, :shards => [] do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'should permit users to configure shards on initializer files, instead of on a yml file.' do
|
40
|
-
expect { User.using(:crazy_shard).create!(:name => 'Joaquim') }.to raise_error
|
40
|
+
expect { User.using(:crazy_shard).create!(:name => 'Joaquim') }.to raise_error(RuntimeError)
|
41
41
|
|
42
42
|
Octopus.setup do |config|
|
43
43
|
config.shards = { :crazy_shard => { :adapter => 'mysql2', :database => 'octopus_shard_5', :username => 'root', :password => '' } }
|
data/spec/octopus/proxy_spec.rb
CHANGED
@@ -6,10 +6,10 @@ describe Octopus::Proxy do
|
|
6
6
|
describe 'creating a new instance', :shards => [] do
|
7
7
|
it 'should initialize all shards and groups' do
|
8
8
|
# FIXME: Don't test implementation details
|
9
|
-
expect(proxy.
|
9
|
+
expect(proxy.shards).to include('canada', 'brazil', 'master', 'sqlite_shard', 'russia', 'alone_shard',
|
10
10
|
'aug2009', 'postgresql_shard', 'aug2010', 'aug2011')
|
11
11
|
|
12
|
-
expect(proxy.
|
12
|
+
expect(proxy.shards).to include('protocol_shard')
|
13
13
|
|
14
14
|
expect(proxy.has_group?('country_shards')).to be true
|
15
15
|
expect(proxy.shards_for_group('country_shards')).to include(:canada, :brazil, :russia)
|
@@ -23,23 +23,17 @@ describe Octopus::Proxy do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'should initialize replicated attribute as false' do
|
26
|
-
expect(proxy.
|
26
|
+
expect(proxy.replicated).to be_falsey
|
27
27
|
end
|
28
28
|
|
29
|
-
it 'should work with
|
30
|
-
config = proxy.
|
29
|
+
it 'should work with thinking sphinx' do
|
30
|
+
config = proxy.config
|
31
31
|
expect(config[:adapter]).to eq('mysql2')
|
32
32
|
expect(config[:database]).to eq('octopus_shard_1')
|
33
33
|
expect(config[:username]).to eq('root')
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
adapters = proxy.instance_variable_get(:@adapters)
|
38
|
-
expect(adapters).to be_kind_of(Set)
|
39
|
-
expect(adapters.to_a).to match_array(%w(sqlite3 mysql2 postgresql))
|
40
|
-
end
|
41
|
-
|
42
|
-
unless Octopus.rails5?
|
36
|
+
unless Octopus.rails50? || Octopus.rails51?
|
43
37
|
it 'should respond correctly to respond_to?(:pk_and_sequence_for)' do
|
44
38
|
expect(proxy.respond_to?(:pk_and_sequence_for)).to be true
|
45
39
|
end
|
@@ -63,22 +57,6 @@ describe Octopus::Proxy do
|
|
63
57
|
end
|
64
58
|
end
|
65
59
|
|
66
|
-
describe '#should_clean_table_name?' do
|
67
|
-
it 'should return true when you have a environment with multiple database types' do
|
68
|
-
expect(proxy.should_clean_table_name?).to be true
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'when using a environment with a single table name' do
|
72
|
-
before(:each) do
|
73
|
-
OctopusHelper.octopus_env = 'production_replicated'
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'should return false' do
|
77
|
-
expect(proxy.should_clean_table_name?).to be false
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
60
|
describe 'should raise error if you have duplicated shard names' do
|
83
61
|
before(:each) do
|
84
62
|
OctopusHelper.octopus_env = 'production_raise_error'
|
@@ -95,11 +73,11 @@ describe Octopus::Proxy do
|
|
95
73
|
end
|
96
74
|
|
97
75
|
it 'should initialize just the master shard' do
|
98
|
-
expect(proxy.
|
76
|
+
expect(proxy.shards.keys).to eq(['master'])
|
99
77
|
end
|
100
78
|
|
101
79
|
it 'should not initialize replication' do
|
102
|
-
expect(proxy.
|
80
|
+
expect(proxy.replicated).to be_nil
|
103
81
|
end
|
104
82
|
end
|
105
83
|
end
|
@@ -110,11 +88,11 @@ describe Octopus::Proxy do
|
|
110
88
|
end
|
111
89
|
|
112
90
|
it 'should have the replicated attribute as true' do
|
113
|
-
expect(proxy.
|
91
|
+
expect(proxy.replicated).to be true
|
114
92
|
end
|
115
93
|
|
116
94
|
it 'should initialize the list of shards' do
|
117
|
-
expect(proxy.
|
95
|
+
expect(proxy.slaves_list).to eq(%w(slave1 slave2 slave3 slave4))
|
118
96
|
end
|
119
97
|
end
|
120
98
|
|
@@ -137,7 +115,7 @@ describe Octopus::Proxy do
|
|
137
115
|
Octopus.instance_variable_set(:@environments, nil)
|
138
116
|
Octopus.config
|
139
117
|
|
140
|
-
expect(proxy.
|
118
|
+
expect(proxy.replicated).to be true
|
141
119
|
expect(Octopus.environments).to eq(%w(staging production))
|
142
120
|
end
|
143
121
|
|
@@ -147,7 +125,7 @@ describe Octopus::Proxy do
|
|
147
125
|
Octopus.instance_variable_set(:@environments, nil)
|
148
126
|
Octopus.config
|
149
127
|
|
150
|
-
expect(proxy.
|
128
|
+
expect(proxy.shards.keys.to_set).to eq(Set.new(%w(slave1 slave2 master)))
|
151
129
|
end
|
152
130
|
|
153
131
|
it 'should initialize correctly the shard octopus_shard value for logging' do
|
@@ -156,7 +134,7 @@ describe Octopus::Proxy do
|
|
156
134
|
Octopus.instance_variable_set(:@environments, nil)
|
157
135
|
Octopus.config
|
158
136
|
|
159
|
-
expect(proxy.
|
137
|
+
expect(proxy.shards['slave1'].spec.config).to have_key :octopus_shard
|
160
138
|
end
|
161
139
|
|
162
140
|
it 'should initialize correctly the shards for the production environment' do
|
@@ -165,7 +143,7 @@ describe Octopus::Proxy do
|
|
165
143
|
Octopus.instance_variable_set(:@environments, nil)
|
166
144
|
Octopus.config
|
167
145
|
|
168
|
-
expect(proxy.
|
146
|
+
expect(proxy.shards.keys.to_set).to eq(Set.new(%w(slave3 slave4 master)))
|
169
147
|
end
|
170
148
|
|
171
149
|
describe 'using the master connection', :shards => [:russia, :master] do
|
@@ -234,12 +212,12 @@ describe Octopus::Proxy do
|
|
234
212
|
|
235
213
|
describe 'should return the connection based on shard_name' do
|
236
214
|
it 'when current_shard is empty' do
|
237
|
-
expect(proxy.select_connection).to eq(proxy.
|
215
|
+
expect(proxy.select_connection).to eq(proxy.shards[:master].connection)
|
238
216
|
end
|
239
217
|
|
240
218
|
it 'when current_shard is a single shard' do
|
241
219
|
proxy.current_shard = :canada
|
242
|
-
expect(proxy.select_connection).to eq(proxy.
|
220
|
+
expect(proxy.select_connection).to eq(proxy.shards[:canada].connection)
|
243
221
|
end
|
244
222
|
end
|
245
223
|
end
|
@@ -38,6 +38,10 @@ describe Octopus::RelationProxy do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
it "can deliver methods in ActiveRecord::Batches correctly" do
|
42
|
+
expect { @relation.find_each(&:inspect) }.not_to raise_error
|
43
|
+
end
|
44
|
+
|
41
45
|
context 'under Rails 4' do
|
42
46
|
it 'is an Octopus::RelationProxy' do
|
43
47
|
expect{@relation.ar_relation}.not_to raise_error
|
@@ -42,7 +42,11 @@ describe 'when the database is replicated' do
|
|
42
42
|
expect(Cat.find(cat3.id).id).to eq(cat3.id)
|
43
43
|
expect(Cat.find(cat3.id).id).to eq(cat3.id)
|
44
44
|
|
45
|
-
|
45
|
+
# Rails 5.1 count the cached queries as regular queries.
|
46
|
+
# TODO: How we can verify if the queries are using cache on Rails 5.1? - @thiagopradi
|
47
|
+
expected_records = Octopus.rails51? ? 19 : 14
|
48
|
+
|
49
|
+
expect(counter.query_count).to eq(expected_records)
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,8 @@ require 'octopus'
|
|
5
5
|
|
6
6
|
Octopus.instance_variable_set(:@directory, File.dirname(__FILE__))
|
7
7
|
|
8
|
+
BaseOctopusMigrationClass = (Octopus.rails4? ? ActiveRecord::Migration : ActiveRecord::Migration[ActiveRecord::VERSION::STRING[0..2]])
|
9
|
+
|
8
10
|
# Requires supporting files with custom matchers and macros, etc,
|
9
11
|
# in ./support/ and its subdirectories.
|
10
12
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module OctopusHelper
|
2
2
|
def self.clean_all_shards(shards)
|
3
3
|
if shards.nil?
|
4
|
-
shards = BlankModel.using(:master).connection.
|
4
|
+
shards = BlankModel.using(:master).connection.shards.keys
|
5
5
|
end
|
6
6
|
|
7
7
|
shards.each do |shard_symbol|
|
@@ -23,7 +23,6 @@ module OctopusHelper
|
|
23
23
|
Thread.current['octopus.current_group'] = nil
|
24
24
|
Thread.current['octopus.current_slave_group'] = nil
|
25
25
|
Thread.current['octopus.block'] = nil
|
26
|
-
Thread.current['octopus.last_current_shard'] = nil
|
27
26
|
|
28
27
|
ActiveRecord::Base.class_variable_set(:@@connection_proxy, nil)
|
29
28
|
end
|
@@ -24,10 +24,8 @@ describe 'octopus.rake' do
|
|
24
24
|
|
25
25
|
Rake::Task['octopus:copy_schema_versions'].invoke
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
ActiveRecord::Base.connection.shard_names.reject { |sh_name| sh_name == 'sqlite_shard' }.each do |shard_name|
|
30
|
-
expect(Octopus.using(shard_name) { ActiveRecord::Migrator.get_all_versions }).to eq([1, 2, 3])
|
27
|
+
ActiveRecord::Base.connection.shard_names.each do |shard_name|
|
28
|
+
expect(Octopus.using(shard_name) { ActiveRecord::SchemaMigration.all.pluck(:version).map(&:to_i).sort }).to eq([1, 2, 3])
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar-octopus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thiago Pradi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2017-07-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -167,7 +167,6 @@ files:
|
|
167
167
|
- ".rspec"
|
168
168
|
- ".rubocop.yml"
|
169
169
|
- ".rubocop_todo.yml"
|
170
|
-
- ".ruby-version"
|
171
170
|
- ".travis.yml"
|
172
171
|
- Appraisals
|
173
172
|
- Gemfile
|
@@ -179,7 +178,7 @@ files:
|
|
179
178
|
- gemfiles/rails41.gemfile
|
180
179
|
- gemfiles/rails42.gemfile
|
181
180
|
- gemfiles/rails5.gemfile
|
182
|
-
-
|
181
|
+
- gemfiles/rails51.gemfile
|
183
182
|
- lib/ar-octopus.rb
|
184
183
|
- lib/octopus.rb
|
185
184
|
- lib/octopus/abstract_adapter.rb
|
@@ -197,6 +196,7 @@ files:
|
|
197
196
|
- lib/octopus/model.rb
|
198
197
|
- lib/octopus/persistence.rb
|
199
198
|
- lib/octopus/proxy.rb
|
199
|
+
- lib/octopus/proxy_config.rb
|
200
200
|
- lib/octopus/railtie.rb
|
201
201
|
- lib/octopus/relation_proxy.rb
|
202
202
|
- lib/octopus/scope_proxy.rb
|
@@ -207,7 +207,6 @@ files:
|
|
207
207
|
- lib/octopus/slave_group.rb
|
208
208
|
- lib/octopus/version.rb
|
209
209
|
- lib/tasks/octopus.rake
|
210
|
-
- rails/init.rb
|
211
210
|
- sample_app/.gitignore
|
212
211
|
- sample_app/.rspec
|
213
212
|
- sample_app/Gemfile
|
@@ -301,6 +300,7 @@ files:
|
|
301
300
|
- spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb
|
302
301
|
- spec/octopus/association_shard_tracking_spec.rb
|
303
302
|
- spec/octopus/collection_proxy_spec.rb
|
303
|
+
- spec/octopus/load_balancing/round_robin_spec.rb
|
304
304
|
- spec/octopus/log_subscriber_spec.rb
|
305
305
|
- spec/octopus/migration_spec.rb
|
306
306
|
- spec/octopus/model_spec.rb
|
@@ -344,7 +344,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
344
344
|
version: '0'
|
345
345
|
requirements: []
|
346
346
|
rubyforge_project:
|
347
|
-
rubygems_version: 2.
|
347
|
+
rubygems_version: 2.2.2
|
348
348
|
signing_key:
|
349
349
|
specification_version: 4
|
350
350
|
summary: Easy Database Sharding for ActiveRecord
|
@@ -367,6 +367,7 @@ test_files:
|
|
367
367
|
- spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb
|
368
368
|
- spec/octopus/association_shard_tracking_spec.rb
|
369
369
|
- spec/octopus/collection_proxy_spec.rb
|
370
|
+
- spec/octopus/load_balancing/round_robin_spec.rb
|
370
371
|
- spec/octopus/log_subscriber_spec.rb
|
371
372
|
- spec/octopus/migration_spec.rb
|
372
373
|
- spec/octopus/model_spec.rb
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.1.5
|
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'rails', 'init')
|
data/rails/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'octopus'
|