ar-octopus 0.0.4 → 0.0.5

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.
data/Rakefile CHANGED
@@ -28,7 +28,8 @@ begin
28
28
  gem.homepage = "http://github.com/tchandy/octopus"
29
29
  gem.authors = ["Thiago Pradi", "Mike Perham", "Amit Agarwal"]
30
30
  gem.add_development_dependency "rspec", ">= 1.2.9"
31
- gem.version = "0.0.4"
31
+ gem.add_dependency('activerecord')
32
+ gem.version = "0.0.5"
32
33
  end
33
34
  Jeweler::GemcutterTasks.new
34
35
  rescue LoadError
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ar-octopus}
8
- s.version = "0.0.4"
8
+ s.version = "0.0.5"
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", "Amit Agarwal"]
@@ -54,6 +54,7 @@ Gem::Specification.new do |s|
54
54
  "spec/octopus/model_spec.rb",
55
55
  "spec/octopus/octopus_spec.rb",
56
56
  "spec/octopus/proxy_spec.rb",
57
+ "spec/octopus/replication_specs.rb",
57
58
  "spec/octopus_helper.rb",
58
59
  "spec/spec.opts",
59
60
  "spec/spec_helper.rb"
@@ -83,6 +84,7 @@ Gem::Specification.new do |s|
83
84
  "spec/octopus/model_spec.rb",
84
85
  "spec/octopus/octopus_spec.rb",
85
86
  "spec/octopus/proxy_spec.rb",
87
+ "spec/octopus/replication_specs.rb",
86
88
  "spec/octopus_helper.rb",
87
89
  "spec/spec_helper.rb"
88
90
  ]
@@ -93,11 +95,14 @@ Gem::Specification.new do |s|
93
95
 
94
96
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
95
97
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
98
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
96
99
  else
97
100
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
101
+ s.add_dependency(%q<activerecord>, [">= 0"])
98
102
  end
99
103
  else
100
104
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
105
+ s.add_dependency(%q<activerecord>, [">= 0"])
101
106
  end
102
107
  end
103
108
 
@@ -53,10 +53,7 @@ module Octopus::Model
53
53
  end
54
54
 
55
55
  def connection
56
- if self.respond_to?(:replicated)
57
- self.connection_proxy().set_replicated_model(self)
58
- end
59
-
56
+ self.connection_proxy().current_model = self
60
57
  self.connection_proxy()
61
58
  end
62
59
  end
@@ -98,7 +95,7 @@ module Octopus::Model
98
95
  include InstanceMethods
99
96
 
100
97
  def replicated_model()
101
- self.cattr_accessor :replicated
98
+ write_inheritable_attribute(:replicated, true)
102
99
  end
103
100
 
104
101
  def has_many(association_id, options = {}, &extension)
@@ -1,17 +1,16 @@
1
1
  require "set"
2
2
 
3
3
  class Octopus::Proxy
4
- attr_accessor :shards, :block, :groups, :current_group, :replicated, :slaves_list, :replicated_models, :using_enabled, :last_current_shard
4
+ attr_accessor :shards, :block, :current_model, :current_shard, :groups, :current_group, :replicated, :slaves_list, :using_enabled, :last_current_shard
5
5
 
6
6
  delegate :increment_open_transactions, :decrement_open_transactions, :to => :select_connection
7
7
 
8
8
  def initialize(config)
9
9
  @shards = {}
10
10
  @groups = {}
11
- @replicated_models = Set.new
12
11
  @replicated = config[Octopus.env()]["replicated"]
13
12
  @shards[:master] = ActiveRecord::Base.connection_pool()
14
- Thread.current[:current_shard] = :master
13
+ @current_shard = :master
15
14
 
16
15
  initialize_shards(config)
17
16
 
@@ -43,10 +42,7 @@ class Octopus::Proxy
43
42
  @slaves_list.delete(:master)
44
43
  @slaves_list = @slaves_list.map {|sym| sym.to_s}.sort
45
44
  end
46
-
47
- def current_shard
48
- Thread.current[:current_shard]
49
- end
45
+
50
46
 
51
47
  def current_shard=(shard_symbol)
52
48
  if shard_symbol.is_a?(Array)
@@ -55,7 +51,7 @@ class Octopus::Proxy
55
51
  raise "Nonexistent Shard Name: #{shard_symbol}" if @shards[shard_symbol].nil?
56
52
  end
57
53
 
58
- Thread.current[:current_shard] = shard_symbol
54
+ @current_shard = shard_symbol
59
55
  end
60
56
 
61
57
  def current_group=(group_symbol)
@@ -68,6 +64,14 @@ class Octopus::Proxy
68
64
  @current_group = group_symbol
69
65
  end
70
66
 
67
+ def current_model=(model)
68
+ if model.is_a?(ActiveRecord::Base)
69
+ @current_model = model.class
70
+ else
71
+ @current_model = model
72
+ end
73
+ end
74
+
71
75
  def select_connection()
72
76
  @shards[shard_name].connection()
73
77
  end
@@ -79,11 +83,7 @@ class Octopus::Proxy
79
83
  current_shard
80
84
  end
81
85
  end
82
-
83
- def set_replicated_model(model)
84
- replicated_models << model.to_s
85
- end
86
-
86
+
87
87
  def add_transaction_record(record)
88
88
  if !select_connection().instance_variable_get(:@_current_transaction_records).nil?
89
89
  select_connection().add_transaction_record(record)
@@ -195,10 +195,9 @@ class Octopus::Proxy
195
195
  end
196
196
 
197
197
  def send_queries_to_selected_slave(method, *args, &block)
198
- #TODO: UGLY code, needs refactor
199
198
  old_shard = self.current_shard
200
-
201
- if args.last =~ /#{replicated_models.to_a.join('|')}/
199
+
200
+ if current_model.read_inheritable_attribute(:replicated)
202
201
  if !using_enabled
203
202
  self.current_shard = slaves_list.shift.to_sym
204
203
  slaves_list << self.current_shard
@@ -11,6 +11,13 @@ describe Octopus::Model do
11
11
  User.using(:canada).count.should == 1
12
12
  User.count.should == 0
13
13
  end
14
+
15
+ it "should select the correct shard" do
16
+ pending()
17
+ # User.using(:canada)
18
+ # User.create!(:name => 'oi')
19
+ # User.using(:master).count.should == 1
20
+ end
14
21
 
15
22
  it "should allow scoping dynamically" do
16
23
  User.using(:canada).using(:master).using(:canada).create!(:name => 'oi')
@@ -144,8 +151,8 @@ describe Octopus::Model do
144
151
 
145
152
  it "should mark the Cat model as replicated" do
146
153
  using_enviroment :production_replicated do
147
- Cat.all.should == []
148
- ActiveRecord::Base.connection_proxy.replicated_models.first.should == "Cat"
154
+ User.read_inheritable_attribute(:replicated).should be_false
155
+ Cat.read_inheritable_attribute(:replicated).should be_true
149
156
  end
150
157
  end
151
158
  end
@@ -57,55 +57,4 @@ describe Octopus::Proxy do
57
57
  end
58
58
  end
59
59
  end
60
-
61
- describe "when the database is replicated" do
62
- before(:each) do
63
- Octopus.stub!(:env).and_return("production_replicated")
64
- @proxy = Octopus::Proxy.new(Octopus.config())
65
- clean_connection_proxy()
66
- end
67
-
68
- it "should have the replicated attribute as true" do
69
- @proxy.replicated.should be_true
70
- end
71
-
72
- it "should initialize the list of shards" do
73
- @proxy.slaves_list.should == ["slave1", "slave2", "slave3", "slave4"]
74
- end
75
-
76
- it "should send all writes queries to master" do
77
- u = User.create!(:name => "Replicated")
78
-
79
- [:slave4, :slave1, :slave2, :slave3].each do |sym|
80
- User.using(sym).count.should == 0
81
- end
82
-
83
- User.using(:master).count.should == 1
84
- end
85
-
86
- it "should send read queries to slaves, using a round robin algorithm" do
87
- u = Cat.create!(:name => "master")
88
- c = Client.create!(:name => "client_master")
89
-
90
- [:slave4, :slave1, :slave2, :slave3].each do |sym|
91
- Cat.using(sym).create!(:name => "Replicated_#{sym}")
92
- end
93
-
94
- Client.find(:first).should_not be_nil
95
- Cat.find(:first).name.should == "Replicated_slave1"
96
- Client.find(:first).should_not be_nil
97
- Cat.find(:first).name.should == "Replicated_slave2"
98
- Client.find(:first).should_not be_nil
99
- Cat.find(:first).name.should == "Replicated_slave3"
100
- Client.find(:first).should_not be_nil
101
- Cat.find(:first).name.should == "Replicated_slave4"
102
- Client.find(:first).should_not be_nil
103
- Cat.find(:first).name.should == "Replicated_slave1"
104
- Client.find(:first).should_not be_nil
105
-
106
- [:slave4, :slave1, :slave2, :slave3].each do |sym|
107
- Cat.using(sym).find_by_name("master").should be_false
108
- end
109
- end
110
- end
111
60
  end
@@ -0,0 +1,46 @@
1
+ describe "when the database is replicated" do
2
+ before(:each) do
3
+ Octopus.stub!(:env).and_return("production_replicated")
4
+ @proxy = Octopus::Proxy.new(Octopus.config())
5
+ clean_connection_proxy()
6
+ end
7
+
8
+ it "should have the replicated attribute as true" do
9
+ @proxy.replicated.should be_true
10
+ end
11
+
12
+ it "should initialize the list of shards" do
13
+ @proxy.slaves_list.should == ["slave1", "slave2", "slave3", "slave4"]
14
+ end
15
+
16
+ it "should send all writes/reads queries to master when you have a replicated model" do
17
+ u = User.create!(:name => "Replicated")
18
+ User.count.should == 1
19
+ User.find(u.id).should == u
20
+ end
21
+
22
+ it "should send read queries to slaves, when you have a replicated model, using a round robin algorithm" do
23
+ u = Cat.create!(:name => "master")
24
+ c = Client.create!(:name => "client_master")
25
+
26
+ [:slave4, :slave1, :slave2, :slave3].each do |sym|
27
+ Cat.using(sym).create!(:name => "Replicated_#{sym}")
28
+ end
29
+
30
+ Client.find(:first).should_not be_nil
31
+ Cat.find(:first).name.should == "Replicated_slave1"
32
+ Client.find(:first).should_not be_nil
33
+ Cat.find(:first).name.should == "Replicated_slave2"
34
+ Client.find(:first).should_not be_nil
35
+ Cat.find(:first).name.should == "Replicated_slave3"
36
+ Client.find(:first).should_not be_nil
37
+ Cat.find(:first).name.should == "Replicated_slave4"
38
+ Client.find(:first).should_not be_nil
39
+ Cat.find(:first).name.should == "Replicated_slave1"
40
+ Client.find(:first).should_not be_nil
41
+
42
+ [:slave4, :slave1, :slave2, :slave3].each do |sym|
43
+ Cat.using(sym).find_by_name("master").should be_false
44
+ end
45
+ end
46
+ end
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: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Thiago Pradi
@@ -36,6 +36,20 @@ dependencies:
36
36
  version: 1.2.9
37
37
  type: :development
38
38
  version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: activerecord
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ type: :runtime
52
+ version_requirements: *id002
39
53
  description: This gem allows you to use sharded databases with ActiveRecord. this also provides a interface for replication and for running migrations with multiples shards.
40
54
  email: tchandy@gmail.com
41
55
  executables: []
@@ -83,6 +97,7 @@ files:
83
97
  - spec/octopus/model_spec.rb
84
98
  - spec/octopus/octopus_spec.rb
85
99
  - spec/octopus/proxy_spec.rb
100
+ - spec/octopus/replication_specs.rb
86
101
  - spec/octopus_helper.rb
87
102
  - spec/spec.opts
88
103
  - spec/spec_helper.rb
@@ -140,5 +155,6 @@ test_files:
140
155
  - spec/octopus/model_spec.rb
141
156
  - spec/octopus/octopus_spec.rb
142
157
  - spec/octopus/proxy_spec.rb
158
+ - spec/octopus/replication_specs.rb
143
159
  - spec/octopus_helper.rb
144
160
  - spec/spec_helper.rb