ar-octopus 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/TODO.txt +3 -1
- data/ar-octopus.gemspec +2 -2
- data/lib/octopus.rb +6 -6
- data/lib/octopus/model.rb +2 -2
- data/spec/config/shards.yml +1 -1
- data/spec/database_models.rb +1 -0
- data/spec/octopus/migration_spec.rb +2 -2
- data/spec/octopus/model_spec.rb +2 -2
- data/spec/octopus/octopus_spec.rb +6 -6
- data/spec/octopus/proxy_spec.rb +6 -6
- data/spec/octopus/replication_specs.rb +16 -6
- data/spec/octopus/sharded_spec.rb +2 -2
- data/spec/octopus_helper.rb +2 -2
- metadata +4 -4
data/Rakefile
CHANGED
@@ -37,7 +37,7 @@ begin
|
|
37
37
|
gem.add_development_dependency "jeweler", ">= 1.4"
|
38
38
|
gem.add_development_dependency "actionpack", ">= 2.3"
|
39
39
|
gem.add_dependency('activerecord', '>= 2.3')
|
40
|
-
gem.version = "0.3.
|
40
|
+
gem.version = "0.3.1"
|
41
41
|
end
|
42
42
|
Jeweler::GemcutterTasks.new
|
43
43
|
rescue LoadError
|
data/TODO.txt
CHANGED
@@ -3,4 +3,6 @@
|
|
3
3
|
- Automatic configuration file for shards.
|
4
4
|
- Support specifics cases of sharding/replication.
|
5
5
|
- Basic algorithm to do load balancing between slaves server (handling servers down)
|
6
|
-
- Support replication + sharding
|
6
|
+
- Support replication + sharding
|
7
|
+
- Wiki about validation
|
8
|
+
- Show where the query is sent in the log
|
data/ar-octopus.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ar-octopus}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Thiago Pradi", "Mike Perham"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-02}
|
13
13
|
s.description = %q{This gem allows you to use sharded databases with ActiveRecord. this also provides a interface for replication and for running migrations with multiples shards.}
|
14
14
|
s.email = %q{tchandy@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/octopus.rb
CHANGED
@@ -13,8 +13,8 @@ module Octopus
|
|
13
13
|
def self.config()
|
14
14
|
@config ||= HashWithIndifferentAccess.new(YAML.load(ERB.new(File.open(Octopus.directory() + "/config/shards.yml").read()).result))[Octopus.env()]
|
15
15
|
|
16
|
-
if @config && @config['
|
17
|
-
self.
|
16
|
+
if @config && @config['environments']
|
17
|
+
self.environments = @config['environments']
|
18
18
|
end
|
19
19
|
|
20
20
|
@config
|
@@ -33,12 +33,12 @@ module Octopus
|
|
33
33
|
yield self
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.
|
37
|
-
@
|
36
|
+
def self.environments=(environments)
|
37
|
+
@environments = environments.map { |element| element.to_s }
|
38
38
|
end
|
39
39
|
|
40
|
-
def self.
|
41
|
-
@
|
40
|
+
def self.environments
|
41
|
+
@environments || ['production']
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.rails3?
|
data/lib/octopus/model.rb
CHANGED
@@ -11,7 +11,7 @@ module Octopus::Model
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def using(shard)
|
14
|
-
return self if defined?(::Rails) && !Octopus.
|
14
|
+
return self if defined?(::Rails) && !Octopus.environments.include?(Rails.env.to_s)
|
15
15
|
|
16
16
|
clean_table_name()
|
17
17
|
hijack_initializer()
|
@@ -43,7 +43,7 @@ module Octopus::Model
|
|
43
43
|
|
44
44
|
def hijack_connection()
|
45
45
|
def self.should_use_normal_connection?
|
46
|
-
(defined?(Rails) && Octopus.config() && !Octopus.
|
46
|
+
(defined?(Rails) && Octopus.config() && !Octopus.environments.include?(Rails.env.to_s)) || self.read_inheritable_attribute(:establish_connection)
|
47
47
|
end
|
48
48
|
|
49
49
|
def self.connection_proxy
|
data/spec/config/shards.yml
CHANGED
data/spec/database_models.rb
CHANGED
@@ -76,7 +76,7 @@ describe Octopus::Migration do
|
|
76
76
|
|
77
77
|
describe "when using replication" do
|
78
78
|
it "should run writes on master when you use replication" do
|
79
|
-
|
79
|
+
using_environment :production_replicated do
|
80
80
|
migrating_to_version 10 do
|
81
81
|
Cat.find_by_name("Replication").should be_nil
|
82
82
|
end
|
@@ -84,7 +84,7 @@ describe Octopus::Migration do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should run in all shards, master or another shards" do
|
87
|
-
|
87
|
+
using_environment :production_replicated do
|
88
88
|
migrating_to_version 11 do
|
89
89
|
[:slave4, :slave1, :slave2, :slave3].each do |sym|
|
90
90
|
Cat.find_by_name("Slaves").should_not be_nil
|
data/spec/octopus/model_spec.rb
CHANGED
@@ -350,13 +350,13 @@ describe Octopus::Model do
|
|
350
350
|
|
351
351
|
describe "#replicated_model method" do
|
352
352
|
it "should be replicated" do
|
353
|
-
|
353
|
+
using_environment :production_replicated do
|
354
354
|
ActiveRecord::Base.connection_proxy.instance_variable_get(:@replicated).should be_true
|
355
355
|
end
|
356
356
|
end
|
357
357
|
|
358
358
|
it "should mark the Cat model as replicated" do
|
359
|
-
|
359
|
+
using_environment :production_replicated do
|
360
360
|
User.read_inheritable_attribute(:replicated).should be_false
|
361
361
|
Cat.read_inheritable_attribute(:replicated).should be_true
|
362
362
|
end
|
@@ -20,19 +20,19 @@ describe Octopus do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
describe "#setup method" do
|
23
|
-
it "should have the default octopus
|
24
|
-
Octopus.
|
23
|
+
it "should have the default octopus environment as production" do
|
24
|
+
Octopus.environments.should == ["production"]
|
25
25
|
end
|
26
26
|
|
27
|
-
it "should allow the user to configure the octopus
|
27
|
+
it "should allow the user to configure the octopus environments" do
|
28
28
|
Octopus.setup do |config|
|
29
|
-
config.
|
29
|
+
config.environments = [:production, :staging]
|
30
30
|
end
|
31
31
|
|
32
|
-
Octopus.
|
32
|
+
Octopus.environments.should == ['production', 'staging']
|
33
33
|
|
34
34
|
Octopus.setup do |config|
|
35
|
-
config.
|
35
|
+
config.environments = [:production]
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
data/spec/octopus/proxy_spec.rb
CHANGED
@@ -37,7 +37,7 @@ describe Octopus::Proxy do
|
|
37
37
|
|
38
38
|
describe "should initialize just the master when you don't have a shards.yml file" do
|
39
39
|
before(:each) do
|
40
|
-
set_octopus_env("
|
40
|
+
set_octopus_env("crazy_environment")
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should initialize just the master shard" do
|
@@ -54,7 +54,7 @@ describe Octopus::Proxy do
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
describe "when you have a replicated
|
57
|
+
describe "when you have a replicated environment" do
|
58
58
|
before(:each) do
|
59
59
|
set_octopus_env("production_replicated")
|
60
60
|
end
|
@@ -74,23 +74,23 @@ describe Octopus::Proxy do
|
|
74
74
|
set_octopus_env("octopus_rails")
|
75
75
|
end
|
76
76
|
|
77
|
-
it "should initialize correctly octopus common variables for the
|
77
|
+
it "should initialize correctly octopus common variables for the environments" do
|
78
78
|
Rails.stub!(:env).and_return('staging')
|
79
79
|
Octopus.instance_variable_set(:@rails_env, nil)
|
80
80
|
Octopus.config()
|
81
81
|
|
82
82
|
proxy.instance_variable_get(:@replicated).should be_true
|
83
83
|
proxy.instance_variable_get(:@verify_connection).should be_true
|
84
|
-
Octopus.
|
84
|
+
Octopus.environments.should == ["staging", "production"]
|
85
85
|
end
|
86
86
|
|
87
|
-
it "should initialize correctly the shards for the staging
|
87
|
+
it "should initialize correctly the shards for the staging environment" do
|
88
88
|
Rails.stub!(:env).and_return('staging')
|
89
89
|
|
90
90
|
proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new([:slave1, :slave2, :master])
|
91
91
|
end
|
92
92
|
|
93
|
-
it "should initialize correctly the shards for the production
|
93
|
+
it "should initialize correctly the shards for the production environment" do
|
94
94
|
Rails.stub!(:env).and_return('production')
|
95
95
|
|
96
96
|
proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new([:slave3, :slave4, :master])
|
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe "when the database is replicated" do
|
4
4
|
it "should send all writes/reads queries to master when you have a non replicated model" do
|
5
|
-
|
5
|
+
using_environment :production_replicated do
|
6
6
|
u = User.create!(:name => "Replicated")
|
7
7
|
User.count.should == 1
|
8
8
|
User.find(u.id).should == u
|
@@ -10,7 +10,7 @@ describe "when the database is replicated" do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should send all writes queries to master" do
|
13
|
-
|
13
|
+
using_environment :production_replicated do
|
14
14
|
Cat.create!(:name => "Slave Cat")
|
15
15
|
Cat.find_by_name("Slave Cat").should be_nil
|
16
16
|
Client.create!(:name => "Slave Client")
|
@@ -19,7 +19,7 @@ describe "when the database is replicated" do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should allow to create multiple models on the master" do
|
22
|
-
|
22
|
+
using_environment :production_replicated do
|
23
23
|
Cat.create!([{:name => "Slave Cat 1"}, {:name => "Slave Cat 2"}])
|
24
24
|
Cat.find_by_name("Slave Cat 1").should be_nil
|
25
25
|
Cat.find_by_name("Slave Cat 2").should be_nil
|
@@ -29,14 +29,14 @@ describe "when the database is replicated" do
|
|
29
29
|
it "should allow #using syntax to send queries to master" do
|
30
30
|
Cat.create!(:name => "Master Cat")
|
31
31
|
|
32
|
-
|
32
|
+
using_environment :production_fully_replicated do
|
33
33
|
Cat.using(:master).find_by_name("Master Cat").should_not be_nil
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should send the count query to a slave" do
|
38
38
|
pending()
|
39
|
-
#
|
39
|
+
# using_environment :production_replicated do
|
40
40
|
# Cat.create!(:name => "Slave Cat")
|
41
41
|
# Cat.count.should == 0
|
42
42
|
# end
|
@@ -51,12 +51,22 @@ describe "when the database is replicated and the entire application is replicat
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should send all writes queries to master" do
|
54
|
-
|
54
|
+
using_environment :production_fully_replicated do
|
55
55
|
Cat.create!(:name => "Slave Cat")
|
56
56
|
Cat.find_by_name("Slave Cat").should be_nil
|
57
57
|
Client.create!(:name => "Slave Client")
|
58
58
|
Client.find_by_name("Slave Client").should be_nil
|
59
59
|
end
|
60
60
|
end
|
61
|
+
|
62
|
+
it "should work with validate_uniquess_of" do
|
63
|
+
Keyboard.create!(:name => "thiago")
|
64
|
+
|
65
|
+
using_environment :production_fully_replicated do
|
66
|
+
k = Keyboard.new(:name => "thiago")
|
67
|
+
k.save.should be_false
|
68
|
+
k.errors.should == {:name=>["has already been taken"]}
|
69
|
+
end
|
70
|
+
end
|
61
71
|
end
|
62
72
|
|
@@ -10,7 +10,7 @@ describe "when the database is not entire sharded" do
|
|
10
10
|
pending()
|
11
11
|
# User.create!(:name => "Thiago")
|
12
12
|
#
|
13
|
-
#
|
13
|
+
# using_environment :not_entire_sharded do
|
14
14
|
# Octopus.using(:russia) do
|
15
15
|
# User.create!(:name => "Thiago")
|
16
16
|
# end
|
@@ -22,7 +22,7 @@ describe "when the database is not entire sharded" do
|
|
22
22
|
it "should pick the shard based on current_shard when you have a sharded model" do
|
23
23
|
Cat.create!(:name => "Thiago")
|
24
24
|
|
25
|
-
|
25
|
+
using_environment :not_entire_sharded do
|
26
26
|
Octopus.using(:russia) do
|
27
27
|
Cat.create!(:name => "Thiago")
|
28
28
|
end
|
data/spec/octopus_helper.rb
CHANGED
@@ -19,9 +19,9 @@ def migrating_to_version(version, &block)
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
22
|
+
def using_environment(environment, &block)
|
23
23
|
begin
|
24
|
-
set_octopus_env(
|
24
|
+
set_octopus_env(environment.to_s)
|
25
25
|
clean_connection_proxy()
|
26
26
|
yield
|
27
27
|
ensure
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar-octopus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Thiago Pradi
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-12-02 00:00:00 -02:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|