ar-octopus 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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