ar-octopus 0.8.2 → 0.8.3
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 +9 -9
- data/.rspec +1 -1
- data/.rubocop.yml +46 -0
- data/.rubocop_todo.yml +52 -0
- data/.ruby-version +1 -1
- data/.travis.yml +3 -9
- data/Appraisals +4 -0
- data/Rakefile +17 -16
- data/ar-octopus.gemspec +22 -16
- data/gemfiles/rails41.gemfile +7 -0
- data/init.rb +1 -1
- data/lib/ar-octopus.rb +1 -1
- data/lib/octopus.rb +38 -37
- data/lib/octopus/abstract_adapter.rb +0 -2
- data/lib/octopus/association.rb +8 -6
- data/lib/octopus/association_shard_tracking.rb +80 -81
- data/lib/octopus/collection_association.rb +7 -5
- data/lib/octopus/collection_proxy.rb +11 -9
- data/lib/octopus/has_and_belongs_to_many_association.rb +5 -3
- data/lib/octopus/load_balancing.rb +3 -2
- data/lib/octopus/load_balancing/round_robin.rb +12 -8
- data/lib/octopus/migration.rb +117 -108
- data/lib/octopus/model.rb +130 -134
- data/lib/octopus/persistence.rb +1 -1
- data/lib/octopus/proxy.rb +345 -339
- data/lib/octopus/railtie.rb +2 -2
- data/lib/octopus/relation_proxy.rb +6 -1
- data/lib/octopus/scope_proxy.rb +38 -36
- data/lib/octopus/shard_tracking.rb +36 -35
- data/lib/octopus/shard_tracking/attribute.rb +12 -14
- data/lib/octopus/shard_tracking/dynamic.rb +7 -3
- data/lib/octopus/singular_association.rb +5 -3
- data/lib/octopus/slave_group.rb +10 -8
- data/lib/octopus/version.rb +1 -1
- data/rails/init.rb +1 -1
- data/sample_app/autotest/discover.rb +2 -2
- data/sample_app/config/application.rb +1 -1
- data/sample_app/config/boot.rb +1 -1
- data/sample_app/config/environments/test.rb +1 -1
- data/sample_app/config/initializers/session_store.rb +1 -1
- data/sample_app/config/initializers/wrap_parameters.rb +1 -1
- data/sample_app/config/routes.rb +1 -1
- data/sample_app/db/migrate/20100720210335_create_sample_users.rb +2 -2
- data/sample_app/db/schema.rb +10 -10
- data/sample_app/db/seeds.rb +3 -3
- data/sample_app/features/step_definitions/seeds_steps.rb +4 -4
- data/sample_app/features/step_definitions/web_steps.rb +3 -4
- data/sample_app/features/support/env.rb +3 -4
- data/sample_app/features/support/paths.rb +4 -4
- data/sample_app/spec/spec_helper.rb +3 -3
- data/spec/migrations/10_create_users_using_replication.rb +3 -3
- data/spec/migrations/11_add_field_in_all_slaves.rb +3 -3
- data/spec/migrations/12_create_users_using_block.rb +7 -7
- data/spec/migrations/13_create_users_using_block_and_using.rb +4 -4
- data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +2 -2
- data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +2 -2
- data/spec/migrations/1_create_users_on_master.rb +3 -3
- data/spec/migrations/2_create_users_on_canada.rb +3 -3
- data/spec/migrations/3_create_users_on_both_shards.rb +3 -3
- data/spec/migrations/4_create_users_on_shards_of_a_group.rb +3 -3
- data/spec/migrations/5_create_users_on_multiples_groups.rb +2 -2
- data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +3 -3
- data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +3 -3
- data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +3 -3
- data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +4 -4
- data/spec/octopus/association_shard_tracking_spec.rb +413 -417
- data/spec/octopus/collection_proxy_spec.rb +6 -5
- data/spec/octopus/log_subscriber_spec.rb +4 -4
- data/spec/octopus/migration_spec.rb +48 -48
- data/spec/octopus/model_spec.rb +267 -292
- data/spec/octopus/octopus_spec.rb +40 -41
- data/spec/octopus/proxy_spec.rb +124 -124
- data/spec/octopus/relation_proxy_spec.rb +32 -32
- data/spec/octopus/replicated_slave_grouped_spec.rb +23 -23
- data/spec/octopus/replication_spec.rb +61 -66
- data/spec/octopus/scope_proxy_spec.rb +56 -10
- data/spec/octopus/sharded_replicated_slave_grouped_spec.rb +29 -29
- data/spec/octopus/sharded_spec.rb +10 -10
- data/spec/spec_helper.rb +6 -6
- data/spec/support/active_record/connection_adapters/modify_config_adapter.rb +1 -3
- data/spec/support/database_connection.rb +2 -2
- data/spec/support/database_models.rb +16 -17
- data/spec/support/octopus_helper.rb +19 -21
- data/spec/support/query_count.rb +1 -3
- data/spec/support/shared_contexts.rb +3 -3
- data/spec/tasks/octopus.rake_spec.rb +10 -10
- metadata +43 -26
@@ -1,64 +1,63 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Octopus, :shards => [] do
|
4
|
-
describe
|
5
|
-
it
|
6
|
-
Octopus.config
|
4
|
+
describe '#config' do
|
5
|
+
it 'should load shards.yml file to start working' do
|
6
|
+
expect(Octopus.config).to be_kind_of(HashWithIndifferentAccess)
|
7
7
|
end
|
8
8
|
|
9
9
|
describe "when config file doesn't exist" do
|
10
10
|
before(:each) do
|
11
|
-
Octopus.
|
11
|
+
allow(Octopus).to receive(:directory).and_return('/tmp')
|
12
12
|
Octopus.instance_variable_set(:@config, nil)
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
16
|
-
Octopus.config
|
15
|
+
it 'should return an empty HashWithIndifferentAccess' do
|
16
|
+
expect(Octopus.config).to eq(HashWithIndifferentAccess.new)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
describe
|
22
|
-
it
|
23
|
-
Octopus.directory
|
21
|
+
describe '#directory' do
|
22
|
+
it 'should return the directory that contains the shards.yml file' do
|
23
|
+
expect(Octopus.directory).to eq(File.expand_path(File.dirname(__FILE__) + '/../'))
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
describe
|
27
|
+
describe '#env' do
|
28
28
|
it "should return 'production' when is outside of a rails application" do
|
29
|
-
Octopus.env
|
29
|
+
expect(Octopus.env).to eq('octopus')
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
describe "#shards=" do
|
33
|
+
describe '#shards=' do
|
35
34
|
after(:each) do
|
36
35
|
Octopus.instance_variable_set(:@config, nil)
|
37
36
|
Octopus::Model.send(:class_variable_set, :@@connection_proxy, nil)
|
38
37
|
end
|
39
38
|
|
40
|
-
it
|
41
|
-
|
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
|
42
41
|
|
43
42
|
Octopus.setup do |config|
|
44
|
-
config.shards = {:crazy_shard => {:adapter =>
|
43
|
+
config.shards = { :crazy_shard => { :adapter => 'mysql2', :database => 'octopus_shard_5', :username => 'root', :password => '' } }
|
45
44
|
end
|
46
45
|
|
47
|
-
|
46
|
+
expect { User.using(:crazy_shard).create!(:name => 'Joaquim') }.not_to raise_error
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
51
|
-
describe
|
52
|
-
it
|
53
|
-
Octopus.environments.
|
50
|
+
describe '#setup' do
|
51
|
+
it 'should have the default octopus environment as production' do
|
52
|
+
expect(Octopus.environments).to eq(['production'])
|
54
53
|
end
|
55
54
|
|
56
|
-
it
|
55
|
+
it 'should allow the user to configure the octopus environments' do
|
57
56
|
Octopus.setup do |config|
|
58
57
|
config.environments = [:production, :staging]
|
59
58
|
end
|
60
59
|
|
61
|
-
Octopus.environments.
|
60
|
+
expect(Octopus.environments).to eq(%w(production staging))
|
62
61
|
|
63
62
|
Octopus.setup do |config|
|
64
63
|
config.environments = [:production]
|
@@ -66,57 +65,57 @@ describe Octopus, :shards => [] do
|
|
66
65
|
end
|
67
66
|
end
|
68
67
|
|
69
|
-
describe
|
68
|
+
describe '#enabled?' do
|
70
69
|
before do
|
71
|
-
Rails = double
|
70
|
+
Rails = double
|
72
71
|
end
|
73
72
|
|
74
73
|
after do
|
75
74
|
Object.send(:remove_const, :Rails)
|
76
75
|
end
|
77
76
|
|
78
|
-
it
|
79
|
-
Rails.
|
77
|
+
it 'should be if octopus is configured and should hook into current environment' do
|
78
|
+
allow(Rails).to receive(:env).and_return('production')
|
80
79
|
|
81
|
-
Octopus.
|
80
|
+
expect(Octopus).to be_enabled
|
82
81
|
end
|
83
82
|
|
84
|
-
it
|
85
|
-
Rails.
|
83
|
+
it 'should not be if octopus should not hook into current environment' do
|
84
|
+
allow(Rails).to receive(:env).and_return('staging')
|
86
85
|
|
87
|
-
Octopus.
|
86
|
+
expect(Octopus).not_to be_enabled
|
88
87
|
end
|
89
88
|
end
|
90
89
|
|
91
|
-
describe
|
90
|
+
describe '#fully_replicated' do
|
92
91
|
before do
|
93
92
|
OctopusHelper.using_environment :production_replicated do
|
94
93
|
OctopusHelper.clean_all_shards([:slave1, :slave2, :slave3, :slave4])
|
95
|
-
4.times { |i| User.using(:"slave#{i+1}").create!(:name =>
|
94
|
+
4.times { |i| User.using(:"slave#{i + 1}").create!(:name => 'Slave User') }
|
96
95
|
end
|
97
96
|
end
|
98
97
|
|
99
|
-
it
|
98
|
+
it 'sends queries to slaves' do
|
100
99
|
OctopusHelper.using_environment :production_replicated do
|
101
|
-
User.count.
|
102
|
-
4.times do |
|
100
|
+
expect(User.count).to eq(0)
|
101
|
+
4.times do |_i|
|
103
102
|
Octopus.fully_replicated do
|
104
|
-
User.count.
|
103
|
+
expect(User.count).to eq(1)
|
105
104
|
end
|
106
105
|
end
|
107
106
|
end
|
108
107
|
end
|
109
108
|
|
110
|
-
it
|
109
|
+
it 'allows nesting' do
|
111
110
|
OctopusHelper.using_environment :production_replicated do
|
112
111
|
Octopus.fully_replicated do
|
113
|
-
User.count.
|
112
|
+
expect(User.count).to eq(1)
|
114
113
|
|
115
114
|
Octopus.fully_replicated do
|
116
|
-
User.count.
|
115
|
+
expect(User.count).to eq(1)
|
117
116
|
end
|
118
117
|
|
119
|
-
User.count.
|
118
|
+
expect(User.count).to eq(1)
|
120
119
|
end
|
121
120
|
end
|
122
121
|
end
|
data/spec/octopus/proxy_spec.rb
CHANGED
@@ -1,299 +1,299 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Octopus::Proxy do
|
4
4
|
let(:proxy) { subject }
|
5
5
|
|
6
|
-
describe
|
7
|
-
it
|
6
|
+
describe 'creating a new instance', :shards => [] do
|
7
|
+
it 'should initialize all shards and groups' do
|
8
8
|
# FIXME: Don't test implementation details
|
9
|
-
proxy.instance_variable_get(:@shards).
|
10
|
-
|
9
|
+
expect(proxy.instance_variable_get(:@shards)).to include('canada', 'brazil', 'master', 'sqlite_shard', 'russia', 'alone_shard',
|
10
|
+
'aug2009', 'postgresql_shard', 'aug2010', 'aug2011')
|
11
11
|
|
12
|
-
proxy.instance_variable_get(:@shards).
|
12
|
+
expect(proxy.instance_variable_get(:@shards)).to include('protocol_shard')
|
13
13
|
|
14
|
-
proxy.has_group?(
|
15
|
-
proxy.shards_for_group(
|
14
|
+
expect(proxy.has_group?('country_shards')).to be true
|
15
|
+
expect(proxy.shards_for_group('country_shards')).to include(:canada, :brazil, :russia)
|
16
16
|
|
17
|
-
proxy.has_group?(
|
18
|
-
proxy.shards_for_group(
|
17
|
+
expect(proxy.has_group?('history_shards')).to be true
|
18
|
+
expect(proxy.shards_for_group('history_shards')).to include(:aug2009, :aug2010, :aug2011)
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
22
|
-
proxy.block.
|
21
|
+
it 'should initialize the block attribute as false' do
|
22
|
+
expect(proxy.block).to be_falsey
|
23
23
|
end
|
24
24
|
|
25
|
-
it
|
26
|
-
proxy.instance_variable_get(:@replicated).
|
25
|
+
it 'should initialize replicated attribute as false' do
|
26
|
+
expect(proxy.instance_variable_get(:@replicated)).to be_falsey
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
29
|
+
it 'should work with thiking sphinx' do
|
30
30
|
config = proxy.instance_variable_get(:@config)
|
31
|
-
config[:adapter].
|
32
|
-
config[:database].
|
33
|
-
config[:username].
|
31
|
+
expect(config[:adapter]).to eq('mysql2')
|
32
|
+
expect(config[:database]).to eq('octopus_shard_1')
|
33
|
+
expect(config[:username]).to eq('root')
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should create a set with all adapters, to ensure that is needed to clean the table name.' do
|
37
37
|
adapters = proxy.instance_variable_get(:@adapters)
|
38
|
-
adapters.
|
39
|
-
adapters.to_a.
|
38
|
+
expect(adapters).to be_kind_of(Set)
|
39
|
+
expect(adapters.to_a).to match_array(%w(sqlite3 mysql2 postgresql))
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'should respond correctly to respond_to?(:pk_and_sequence_for)' do
|
43
|
-
proxy.respond_to?(:pk_and_sequence_for).
|
43
|
+
expect(proxy.respond_to?(:pk_and_sequence_for)).to be true
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'should respond correctly to respond_to?(:primary_key)' do
|
47
|
-
proxy.respond_to?(:primary_key).
|
47
|
+
expect(proxy.respond_to?(:primary_key)).to be true
|
48
48
|
end
|
49
49
|
|
50
50
|
context 'when an adapter that modifies the config' do
|
51
|
-
before
|
52
|
-
after
|
51
|
+
before { OctopusHelper.octopus_env = 'modify_config' }
|
52
|
+
after { OctopusHelper.octopus_env = 'octopus' }
|
53
53
|
|
54
54
|
it 'should not fail with missing adapter second time round' do
|
55
|
-
|
56
|
-
Thread.current[
|
55
|
+
skip 'This test was actually failing because of a typo in the error message.'
|
56
|
+
Thread.current['octopus.current_shard'] = :modify_config_read
|
57
57
|
|
58
|
-
|
58
|
+
expect { Octopus::Proxy.new(Octopus.config) }.not_to raise_error
|
59
59
|
|
60
|
-
Thread.current[
|
60
|
+
Thread.current['octopus.current_shard'] = nil
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
describe
|
64
|
+
describe '#should_clean_table_name?' do
|
65
65
|
it 'should return true when you have a environment with multiple database types' do
|
66
|
-
proxy.should_clean_table_name
|
66
|
+
expect(proxy.should_clean_table_name?).to be true
|
67
67
|
end
|
68
68
|
|
69
|
-
context
|
69
|
+
context 'when using a environment with a single table name' do
|
70
70
|
before(:each) do
|
71
|
-
OctopusHelper.
|
71
|
+
OctopusHelper.octopus_env = 'production_replicated'
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'should return false' do
|
75
|
-
proxy.should_clean_table_name
|
75
|
+
expect(proxy.should_clean_table_name?).to be false
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
-
describe
|
80
|
+
describe 'should raise error if you have duplicated shard names' do
|
81
81
|
before(:each) do
|
82
|
-
OctopusHelper.
|
82
|
+
OctopusHelper.octopus_env = 'production_raise_error'
|
83
83
|
end
|
84
84
|
|
85
|
-
it
|
86
|
-
|
85
|
+
it 'should raise the error' do
|
86
|
+
expect { proxy }.to raise_error('You have duplicated shard names!')
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
describe "should initialize just the master when you don't have a shards.yml file" do
|
91
91
|
before(:each) do
|
92
|
-
OctopusHelper.
|
92
|
+
OctopusHelper.octopus_env = 'crazy_environment'
|
93
93
|
end
|
94
94
|
|
95
|
-
it
|
96
|
-
proxy.instance_variable_get(:@shards).keys.
|
95
|
+
it 'should initialize just the master shard' do
|
96
|
+
expect(proxy.instance_variable_get(:@shards).keys).to eq(['master'])
|
97
97
|
end
|
98
98
|
|
99
|
-
it
|
100
|
-
proxy.instance_variable_get(:@replicated).
|
99
|
+
it 'should not initialize replication' do
|
100
|
+
expect(proxy.instance_variable_get(:@replicated)).to be_nil
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
describe
|
105
|
+
describe 'when you have a replicated environment' do
|
106
106
|
before(:each) do
|
107
|
-
OctopusHelper.
|
107
|
+
OctopusHelper.octopus_env = 'production_replicated'
|
108
108
|
end
|
109
109
|
|
110
|
-
it
|
111
|
-
proxy.instance_variable_get(:@replicated).
|
110
|
+
it 'should have the replicated attribute as true' do
|
111
|
+
expect(proxy.instance_variable_get(:@replicated)).to be true
|
112
112
|
end
|
113
113
|
|
114
|
-
it
|
115
|
-
proxy.instance_variable_get(:@slaves_list).
|
114
|
+
it 'should initialize the list of shards' do
|
115
|
+
expect(proxy.instance_variable_get(:@slaves_list)).to eq(%w(slave1 slave2 slave3 slave4))
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
-
describe
|
119
|
+
describe 'when you have a rails application' do
|
120
120
|
before(:each) do
|
121
|
-
Rails = double
|
122
|
-
OctopusHelper.
|
121
|
+
Rails = double
|
122
|
+
OctopusHelper.octopus_env = 'octopus_rails'
|
123
123
|
end
|
124
124
|
|
125
125
|
after(:each) do
|
126
126
|
Object.send(:remove_const, :Rails)
|
127
127
|
Octopus.instance_variable_set(:@config, nil)
|
128
128
|
Octopus.instance_variable_set(:@rails_env, nil)
|
129
|
-
OctopusHelper.clean_connection_proxy
|
129
|
+
OctopusHelper.clean_connection_proxy
|
130
130
|
end
|
131
131
|
|
132
|
-
it
|
133
|
-
Rails.
|
132
|
+
it 'should initialize correctly octopus common variables for the environments' do
|
133
|
+
allow(Rails).to receive(:env).and_return('staging')
|
134
134
|
Octopus.instance_variable_set(:@rails_env, nil)
|
135
135
|
Octopus.instance_variable_set(:@environments, nil)
|
136
|
-
Octopus.config
|
136
|
+
Octopus.config
|
137
137
|
|
138
|
-
proxy.instance_variable_get(:@replicated).
|
139
|
-
Octopus.environments.
|
138
|
+
expect(proxy.instance_variable_get(:@replicated)).to be true
|
139
|
+
expect(Octopus.environments).to eq(%w(staging production))
|
140
140
|
end
|
141
141
|
|
142
|
-
it
|
143
|
-
Rails.
|
142
|
+
it 'should initialize correctly the shards for the staging environment' do
|
143
|
+
allow(Rails).to receive(:env).and_return('staging')
|
144
144
|
Octopus.instance_variable_set(:@rails_env, nil)
|
145
145
|
Octopus.instance_variable_set(:@environments, nil)
|
146
|
-
Octopus.config
|
146
|
+
Octopus.config
|
147
147
|
|
148
|
-
proxy.instance_variable_get(:@shards).keys.to_set.
|
148
|
+
expect(proxy.instance_variable_get(:@shards).keys.to_set).to eq(Set.new(%w(slave1 slave2 master)))
|
149
149
|
end
|
150
150
|
|
151
|
-
it
|
152
|
-
Rails.
|
151
|
+
it 'should initialize correctly the shard octopus_shard value for logging' do
|
152
|
+
allow(Rails).to receive(:env).and_return('staging')
|
153
153
|
Octopus.instance_variable_set(:@rails_env, nil)
|
154
154
|
Octopus.instance_variable_set(:@environments, nil)
|
155
|
-
Octopus.config
|
155
|
+
Octopus.config
|
156
156
|
|
157
|
-
proxy.instance_variable_get(:@shards)['slave1'].spec.config.
|
157
|
+
expect(proxy.instance_variable_get(:@shards)['slave1'].spec.config).to have_key :octopus_shard
|
158
158
|
end
|
159
159
|
|
160
|
-
it
|
161
|
-
Rails.
|
160
|
+
it 'should initialize correctly the shards for the production environment' do
|
161
|
+
allow(Rails).to receive(:env).and_return('production')
|
162
162
|
Octopus.instance_variable_set(:@rails_env, nil)
|
163
163
|
Octopus.instance_variable_set(:@environments, nil)
|
164
|
-
Octopus.config
|
164
|
+
Octopus.config
|
165
165
|
|
166
|
-
proxy.instance_variable_get(:@shards).keys.to_set.
|
166
|
+
expect(proxy.instance_variable_get(:@shards).keys.to_set).to eq(Set.new(%w(slave3 slave4 master)))
|
167
167
|
end
|
168
168
|
|
169
|
-
describe
|
169
|
+
describe 'using the master connection', :shards => [:russia, :master] do
|
170
170
|
before(:each) do
|
171
|
-
Rails.
|
171
|
+
allow(Rails).to receive(:env).and_return('development')
|
172
172
|
end
|
173
173
|
|
174
|
-
it
|
175
|
-
user = User.create!(:name =>
|
176
|
-
user.name =
|
177
|
-
user.save
|
178
|
-
User.find_by_name(
|
174
|
+
it 'should use the master connection' do
|
175
|
+
user = User.create!(:name => 'Thiago')
|
176
|
+
user.name = 'New Thiago'
|
177
|
+
user.save
|
178
|
+
expect(User.find_by_name('New Thiago')).not_to be_nil
|
179
179
|
end
|
180
180
|
|
181
|
-
it
|
182
|
-
user = User.using(:russia).create!(:name =>
|
181
|
+
it 'should work when using using syntax' do
|
182
|
+
user = User.using(:russia).create!(:name => 'Thiago')
|
183
183
|
|
184
|
-
user.name =
|
185
|
-
user.save
|
184
|
+
user.name = 'New Thiago'
|
185
|
+
user.save
|
186
186
|
|
187
|
-
User.using(:russia).find_by_name(
|
188
|
-
User.find_by_name(
|
187
|
+
expect(User.using(:russia).find_by_name('New Thiago')).to eq(user)
|
188
|
+
expect(User.find_by_name('New Thiago')).to eq(user)
|
189
189
|
end
|
190
190
|
|
191
|
-
it
|
191
|
+
it 'should work when using blocks' do
|
192
192
|
Octopus.using(:russia) do
|
193
|
-
@user = User.create!(:name =>
|
193
|
+
@user = User.create!(:name => 'Thiago')
|
194
194
|
end
|
195
195
|
|
196
|
-
User.find_by_name(
|
196
|
+
expect(User.find_by_name('Thiago')).to eq(@user)
|
197
197
|
end
|
198
198
|
|
199
|
-
it
|
200
|
-
u = Client.create!(:name =>
|
201
|
-
i = Item.create(:name =>
|
199
|
+
it 'should work with associations' do
|
200
|
+
u = Client.create!(:name => 'Thiago')
|
201
|
+
i = Item.create(:name => 'Item')
|
202
202
|
u.items << i
|
203
|
-
u.save
|
203
|
+
u.save
|
204
204
|
end
|
205
205
|
end
|
206
206
|
end
|
207
207
|
|
208
|
-
describe
|
209
|
-
describe
|
210
|
-
it
|
211
|
-
proxy.shard_name.
|
208
|
+
describe 'returning the correct connection' do
|
209
|
+
describe 'should return the shard name' do
|
210
|
+
it 'when current_shard is empty' do
|
211
|
+
expect(proxy.shard_name).to eq(:master)
|
212
212
|
end
|
213
213
|
|
214
|
-
it
|
214
|
+
it 'when current_shard is a single shard' do
|
215
215
|
proxy.current_shard = :canada
|
216
|
-
proxy.shard_name.
|
216
|
+
expect(proxy.shard_name).to eq(:canada)
|
217
217
|
end
|
218
218
|
|
219
|
-
it
|
219
|
+
it 'when current_shard is more than one shard' do
|
220
220
|
proxy.current_shard = [:russia, :brazil]
|
221
|
-
proxy.shard_name.
|
221
|
+
expect(proxy.shard_name).to eq(:russia)
|
222
222
|
end
|
223
223
|
end
|
224
224
|
|
225
|
-
describe
|
226
|
-
it
|
227
|
-
proxy.select_connection
|
225
|
+
describe 'should return the connection based on shard_name' do
|
226
|
+
it 'when current_shard is empty' do
|
227
|
+
expect(proxy.select_connection).to eq(proxy.instance_variable_get(:@shards)[:master].connection)
|
228
228
|
end
|
229
229
|
|
230
|
-
it
|
230
|
+
it 'when current_shard is a single shard' do
|
231
231
|
proxy.current_shard = :canada
|
232
|
-
proxy.select_connection
|
232
|
+
expect(proxy.select_connection).to eq(proxy.instance_variable_get(:@shards)[:canada].connection)
|
233
233
|
end
|
234
234
|
end
|
235
235
|
end
|
236
236
|
|
237
|
-
describe
|
237
|
+
describe 'saving multiple sharded objects at once' do
|
238
238
|
before :each do
|
239
239
|
@p = MmorpgPlayer.using(:alone_shard).create!(:player_name => 'Thiago')
|
240
240
|
end
|
241
241
|
|
242
242
|
subject { @p.save! }
|
243
243
|
|
244
|
-
context
|
244
|
+
context 'when the objects are created with #new and saved one at a time' do
|
245
245
|
before :each do
|
246
246
|
@p.weapons.create!(:name => 'battleaxe', :hand => 'right')
|
247
247
|
@p.skills.create!(:name => 'smiting', :weapon => @p.weapons[0])
|
248
248
|
end
|
249
249
|
|
250
|
-
it
|
250
|
+
it 'should save all associated objects on the correct shard' do
|
251
251
|
expect { subject }.to_not raise_error
|
252
252
|
end
|
253
253
|
end
|
254
254
|
|
255
|
-
context
|
255
|
+
context 'when the objects are created with #new and saved at the same time' do
|
256
256
|
before :each do
|
257
257
|
@p.weapons.new(:name => 'battleaxe', :hand => 'right')
|
258
258
|
@p.skills.new(:name => 'smiting', :weapon => @p.weapons[0])
|
259
259
|
end
|
260
260
|
|
261
|
-
it
|
261
|
+
it 'should save all associated objects on the correct shard' do
|
262
262
|
expect { subject }.to_not raise_error
|
263
263
|
end
|
264
264
|
end
|
265
265
|
end
|
266
266
|
|
267
|
-
describe
|
267
|
+
describe 'connection reuse' do
|
268
268
|
before :each do
|
269
|
-
@item_brazil_conn = Item.using(:brazil).new(:name => 'Brazil Item').connection.select_connection
|
270
|
-
@item_canada_conn = Item.using(:canada).new(:name => 'Canada Item').connection.select_connection
|
269
|
+
@item_brazil_conn = Item.using(:brazil).new(:name => 'Brazil Item').class.connection.select_connection
|
270
|
+
@item_canada_conn = Item.using(:canada).new(:name => 'Canada Item').class.connection.select_connection
|
271
271
|
end
|
272
272
|
|
273
|
-
it
|
274
|
-
Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.
|
275
|
-
Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.
|
273
|
+
it 'reuses connections' do
|
274
|
+
expect(Item.using(:brazil).new(:name => 'Another Brazil Item').class.connection.select_connection).to eq(@item_brazil_conn)
|
275
|
+
expect(Item.using(:canada).new(:name => 'Another Canada Item').class.connection.select_connection).to eq(@item_canada_conn)
|
276
276
|
end
|
277
277
|
|
278
|
-
it
|
279
|
-
Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.
|
280
|
-
Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.
|
278
|
+
it 'reuses connections after clear_active_connections! is called' do
|
279
|
+
expect(Item.using(:brazil).new(:name => 'Another Brazil Item').class.connection.select_connection).to eq(@item_brazil_conn)
|
280
|
+
expect(Item.using(:canada).new(:name => 'Another Canada Item').class.connection.select_connection).to eq(@item_canada_conn)
|
281
281
|
end
|
282
282
|
|
283
|
-
it
|
283
|
+
it 'creates new connections after clear_all_connections! is called' do
|
284
284
|
Item.clear_all_connections!
|
285
|
-
Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.
|
286
|
-
Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.
|
285
|
+
expect(Item.using(:brazil).new(:name => 'Another Brazil Item').class.connection.select_connection).not_to eq(@item_brazil_conn)
|
286
|
+
expect(Item.using(:canada).new(:name => 'Another Canada Item').class.connection.select_connection).not_to eq(@item_canada_conn)
|
287
287
|
end
|
288
288
|
|
289
|
-
it
|
290
|
-
Item.connected
|
291
|
-
ActiveRecord::Base.connected
|
289
|
+
it 'is consistent with connected?' do
|
290
|
+
expect(Item.connected?).to be true
|
291
|
+
expect(ActiveRecord::Base.connected?).to be true
|
292
292
|
|
293
293
|
Item.clear_all_connections!
|
294
294
|
|
295
|
-
Item.connected
|
296
|
-
ActiveRecord::Base.connected
|
295
|
+
expect(Item.connected?).to be false
|
296
|
+
expect(ActiveRecord::Base.connected?).to be false
|
297
297
|
end
|
298
298
|
end
|
299
299
|
end
|