replica 1.0.1 → 1.0.2
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/VERSION +1 -1
- data/lib/replica.rb +46 -25
- data/test/helper.rb +2 -2
- data/test/replica_test.rb +7 -6
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/lib/replica.rb
CHANGED
@@ -11,6 +11,9 @@ module ActiveRecord # :nodoc:
|
|
11
11
|
# end
|
12
12
|
# the first account will be found on the slave DB
|
13
13
|
#
|
14
|
+
# For one-liners you can simply do
|
15
|
+
# Account.with_slave.first
|
16
|
+
#
|
14
17
|
# this is the same as:
|
15
18
|
# Account.with_replica(:slave) do
|
16
19
|
# Account.first
|
@@ -18,7 +21,7 @@ module ActiveRecord # :nodoc:
|
|
18
21
|
def with_slave(&block)
|
19
22
|
with_replica(:slave, &block)
|
20
23
|
end
|
21
|
-
|
24
|
+
|
22
25
|
# See with_slave
|
23
26
|
def with_master(&block)
|
24
27
|
with_replica(nil, &block)
|
@@ -27,11 +30,11 @@ module ActiveRecord # :nodoc:
|
|
27
30
|
def with_slave_if(condition, &block)
|
28
31
|
condition ? with_slave(&block) : with_master(&block)
|
29
32
|
end
|
30
|
-
|
33
|
+
|
31
34
|
def with_slave_unless(condition, &block)
|
32
35
|
with_slave_if(!condition, &block)
|
33
36
|
end
|
34
|
-
|
37
|
+
|
35
38
|
# Name of the connection pool. Used by ConnectionHandler to retrieve the current connection pool.
|
36
39
|
def connection_pool_name # :nodoc:
|
37
40
|
replica = current_replica_name
|
@@ -44,7 +47,7 @@ module ActiveRecord # :nodoc:
|
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
47
|
-
# Specify which database to use.
|
50
|
+
# Specify which database to use.
|
48
51
|
#
|
49
52
|
# Example:
|
50
53
|
# database.yml
|
@@ -53,22 +56,31 @@ module ActiveRecord # :nodoc:
|
|
53
56
|
# ...
|
54
57
|
#
|
55
58
|
# Account.with_replica(:slave) { Account.count }
|
59
|
+
# Account.with_replica(:slave).count
|
56
60
|
#
|
57
61
|
def with_replica(replica_name, &block)
|
62
|
+
if block_given?
|
63
|
+
with_replica_block(replica_name, &block)
|
64
|
+
else
|
65
|
+
Proxy.new(self, replica_name)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def with_replica_block(replica_name, &block)
|
58
70
|
old_replica_name = current_replica_name
|
59
71
|
begin
|
60
72
|
self.current_replica_name = replica_name
|
61
73
|
rescue ActiveRecord::AdapterNotSpecified => e
|
62
74
|
self.current_replica_name = old_replica_name
|
63
75
|
logger.warn("Failed to establish replica connection: #{e.message} - defaulting to master")
|
64
|
-
end
|
76
|
+
end
|
65
77
|
yield
|
66
78
|
ensure
|
67
79
|
self.current_replica_name = old_replica_name
|
68
80
|
end
|
69
81
|
|
70
82
|
private
|
71
|
-
|
83
|
+
|
72
84
|
def current_replica_name
|
73
85
|
Thread.current[replica_key]
|
74
86
|
end
|
@@ -78,47 +90,56 @@ module ActiveRecord # :nodoc:
|
|
78
90
|
|
79
91
|
establish_replica_connection(new_replica_name) unless connected_to_replica?
|
80
92
|
end
|
81
|
-
|
93
|
+
|
82
94
|
def establish_replica_connection(replica_name)
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
95
|
+
name = replica_name ? "#{RAILS_ENV}_#{replica_name}" : RAILS_ENV
|
96
|
+
spec = configurations[name]
|
97
|
+
raise AdapterNotSpecified.new("No database defined by #{name} in database.yml") if spec.nil?
|
98
|
+
|
99
|
+
connection_handler.establish_connection(connection_pool_name, ConnectionSpecification.new(spec, "#{spec['adapter']}_connection"))
|
88
100
|
end
|
89
|
-
|
101
|
+
|
90
102
|
def connected_to_replica?
|
91
103
|
connection_handler.connection_pools.has_key?(connection_pool_name)
|
92
104
|
end
|
93
|
-
|
105
|
+
|
94
106
|
def replica_key
|
95
107
|
@replica_key ||= "#{name}_replica"
|
96
108
|
end
|
97
|
-
|
109
|
+
|
110
|
+
class Proxy
|
111
|
+
def initialize(target, replica)
|
112
|
+
@target = target
|
113
|
+
@replica = replica
|
114
|
+
end
|
115
|
+
|
116
|
+
def method_missing(method, *args)
|
117
|
+
@target.with_replica_block(@replica) { @target.send(method, *args) }
|
118
|
+
end
|
119
|
+
end
|
98
120
|
end
|
99
121
|
end
|
100
122
|
Base.extend(Base::Replica)
|
101
|
-
|
123
|
+
|
102
124
|
# The only difference here is that we use klass.connection_pool_name
|
103
125
|
# instead of klass.name as the pool key
|
104
126
|
module ConnectionAdapters # :nodoc:
|
105
127
|
class ConnectionHandler # :nodoc:
|
106
|
-
|
128
|
+
|
107
129
|
def retrieve_connection_pool(klass)
|
108
130
|
pool = @connection_pools[klass.connection_pool_name]
|
109
131
|
return pool if pool
|
110
132
|
return nil if ActiveRecord::Base == klass
|
111
133
|
retrieve_connection_pool klass.superclass
|
112
134
|
end
|
113
|
-
|
135
|
+
|
114
136
|
def remove_connection(klass)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
137
|
+
pool = @connection_pools[klass.connection_pool_name]
|
138
|
+
@connection_pools.delete_if { |key, value| value == pool }
|
139
|
+
pool.disconnect! if pool
|
140
|
+
pool.spec.config if pool
|
141
|
+
end
|
142
|
+
|
121
143
|
end
|
122
144
|
end
|
123
145
|
end
|
124
|
-
|
data/test/helper.rb
CHANGED
@@ -20,7 +20,7 @@ load(File.dirname(__FILE__) + "/schema.rb")
|
|
20
20
|
|
21
21
|
|
22
22
|
class Test::Unit::TestCase
|
23
|
-
|
23
|
+
|
24
24
|
def assert_using_master_db(klass)
|
25
25
|
assert_equal('replica_test', klass.connection.instance_variable_get(:@config)[:database])
|
26
26
|
end
|
@@ -28,5 +28,5 @@ class Test::Unit::TestCase
|
|
28
28
|
def assert_using_slave_db(klass)
|
29
29
|
assert_equal('replica_test_slave', klass.connection.instance_variable_get(:@config)[:database])
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
end
|
data/test/replica_test.rb
CHANGED
@@ -13,7 +13,7 @@ class ReplicaTest < ActiveRecord::TestCase
|
|
13
13
|
should "default to the master database" do
|
14
14
|
Account.create!
|
15
15
|
|
16
|
-
ActiveRecord::Base.with_slave { assert_using_master_db(Account) }
|
16
|
+
ActiveRecord::Base.with_slave { assert_using_master_db(Account) }
|
17
17
|
Account.with_slave { assert_using_master_db(Account) }
|
18
18
|
Ticket.with_slave { assert_using_master_db(Account) }
|
19
19
|
end
|
@@ -36,6 +36,7 @@ class ReplicaTest < ActiveRecord::TestCase
|
|
36
36
|
|
37
37
|
assert_not_equal Account.count, ActiveRecord::Base.with_slave { Account.count }
|
38
38
|
assert_not_equal Account.count, Account.with_slave { Account.count }
|
39
|
+
assert_not_equal Account.count, Account.with_slave.count
|
39
40
|
assert_equal Account.count, Ticket.with_slave { Account.count }
|
40
41
|
end
|
41
42
|
|
@@ -67,25 +68,25 @@ class ReplicaTest < ActiveRecord::TestCase
|
|
67
68
|
|
68
69
|
should "support conditional methods" do
|
69
70
|
assert_using_master_db(Account)
|
70
|
-
|
71
|
+
|
71
72
|
Account.with_slave_if(true) do
|
72
73
|
assert_using_slave_db(Account)
|
73
74
|
end
|
74
|
-
|
75
|
+
|
75
76
|
assert_using_master_db(Account)
|
76
77
|
|
77
78
|
Account.with_slave_if(false) do
|
78
79
|
assert_using_master_db(Account)
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
Account.with_slave_unless(true) do
|
82
83
|
assert_using_master_db(Account)
|
83
84
|
end
|
84
|
-
|
85
|
+
|
85
86
|
Account.with_slave_unless(false) do
|
86
87
|
assert_using_slave_db(Account)
|
87
88
|
end
|
88
|
-
|
89
|
+
|
89
90
|
end
|
90
91
|
|
91
92
|
should_eventually "support nested with_* blocks" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: replica
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Chapweske
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-01-
|
13
|
+
date: 2010-01-28 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|