active_shard 0.2.0 → 0.2.1
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/README.md
CHANGED
@@ -3,43 +3,6 @@ ActiveShard - Multi-schema sharding for ActiveRecord
|
|
3
3
|
|
4
4
|
ActiveShard is a library built primarily for sharding in ActiveRecord. It also supports multiple databases with differing schemas. As with the other sharding libraries for ActiveRecord (there are a few), this library represents the best solution to the authors' sharding needs. If you've been unhappy with other options, ActiveShard might be for you.
|
5
5
|
|
6
|
-
|
7
|
-
## CAVEATS ##
|
8
|
-
|
9
|
-
### Railtie isn't finished ... ###
|
10
|
-
|
11
|
-
... so there are some additional steps you'll need to take to get this working. Specifically:
|
12
|
-
|
13
|
-
Add the following to the end of your config/application.rb:
|
14
|
-
|
15
|
-
ActiveShard.config do |c|
|
16
|
-
definitions = ActiveShard::ShardDefinition.from_yaml_file( File.expand_path( '../shards.yml', __FILE__ ) )
|
17
|
-
|
18
|
-
definitions[ Rails.env.to_sym ].each do |shard|
|
19
|
-
c.add_shard( shard )
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
require 'active_shard/active_record'
|
24
|
-
|
25
|
-
ActiveRecord::Base.send( :include, ActiveShard::ActiveRecord::ShardSupport )
|
26
|
-
|
27
|
-
ActiveRecord::Base.connection_handler =
|
28
|
-
ActiveShard::ActiveRecord::ConnectionHandler.new(
|
29
|
-
ActiveShard.config.shard_definitions,
|
30
|
-
:shard_lookup => ActiveShard::ShardLookupHandler.new( :scope => ActiveShard.scope, :config => ActiveShard.config )
|
31
|
-
)
|
32
|
-
|
33
|
-
Once we complete the ActiveShard Railtie, these lines will not be necessary.
|
34
|
-
|
35
|
-
|
36
|
-
### Where are the specs? ###
|
37
|
-
|
38
|
-
Good eye. This library is being extracted from an existing project where application-specific tests were written to test the sharding functionality.
|
39
|
-
|
40
|
-
Generic and more detailed specs are being written and will be added shortly.
|
41
|
-
|
42
|
-
|
43
6
|
## Design goals ##
|
44
7
|
|
45
8
|
The fundamental purpose of ActiveShard is to provide a framework that allows ActiveRecord to connect to multiple databases with multiple different schemas. All other features are a subset of this framework (sharding, replication, etc).
|
@@ -74,7 +37,7 @@ Install bundle:
|
|
74
37
|
|
75
38
|
Add to config/application.rb, right under "require 'rails/all'":
|
76
39
|
|
77
|
-
require 'active_shard/
|
40
|
+
require 'active_shard/railtie'
|
78
41
|
|
79
42
|
|
80
43
|
## Most common usage ##
|
data/lib/active_shard.rb
CHANGED
@@ -146,16 +146,18 @@ module ActiveShard
|
|
146
146
|
# @return the return value from the provided block
|
147
147
|
#
|
148
148
|
def with( scopes={}, &block )
|
149
|
-
ret
|
149
|
+
ret = nil
|
150
|
+
memento = nil
|
150
151
|
|
151
152
|
begin
|
152
|
-
activate_shards( scopes )
|
153
|
+
memento = activate_shards( scopes )
|
153
154
|
|
154
155
|
ret = block.call()
|
155
156
|
ensure
|
156
|
-
pop_to(
|
157
|
-
ret
|
157
|
+
pop_to( memento )
|
158
158
|
end
|
159
|
+
|
160
|
+
ret
|
159
161
|
end
|
160
162
|
|
161
163
|
# Pushes active shards onto the scope without a block.
|
@@ -12,7 +12,6 @@ module ActiveShard
|
|
12
12
|
|
13
13
|
# Initializes a new ConnectionHandler
|
14
14
|
#
|
15
|
-
# @param [Array<ShardDefinition>] shard_definitions
|
16
15
|
# @param [Hash] options
|
17
16
|
# @option options [ShardLookupHandler, #lookup_active_shard] :shard_lookup
|
18
17
|
#
|
@@ -20,7 +19,7 @@ module ActiveShard
|
|
20
19
|
@shard_lookup = options[ :shard_lookup ]
|
21
20
|
|
22
21
|
@shard_definitions = []
|
23
|
-
@connection_pools =
|
22
|
+
@connection_pools = ConnectionPoolHash.new( self )
|
24
23
|
@schema_pools = {}
|
25
24
|
end
|
26
25
|
|
@@ -118,9 +117,41 @@ module ActiveShard
|
|
118
117
|
schema_name = definition.nil? ? args.shift : definition.schema
|
119
118
|
shard_name = definition.nil? ? args.shift : definition.name
|
120
119
|
|
121
|
-
|
120
|
+
PoolKey.new( schema_name, shard_name )
|
122
121
|
end
|
123
122
|
|
123
|
+
class PoolKey
|
124
|
+
attr_reader :schema, :shard
|
125
|
+
|
126
|
+
def initialize( schema, shard )
|
127
|
+
@schema = schema.nil? ? nil : schema.to_sym
|
128
|
+
@shard = shard.nil? ? nil : shard.to_sym
|
129
|
+
end
|
130
|
+
|
131
|
+
def hash
|
132
|
+
[self.schema, self.shard].hash
|
133
|
+
end
|
134
|
+
|
135
|
+
def eql?(other)
|
136
|
+
(self.schema == other.schema &&
|
137
|
+
self.shard == other.shard)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class ConnectionPoolHash < Hash
|
142
|
+
def initialize( connection_handler )
|
143
|
+
@connection_handler = connection_handler
|
144
|
+
end
|
145
|
+
|
146
|
+
def [](val)
|
147
|
+
case val
|
148
|
+
when PoolKey
|
149
|
+
super
|
150
|
+
else
|
151
|
+
@connection_handler.retrieve_connection_pool( val.constantize )
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
124
155
|
|
125
156
|
end
|
126
157
|
end
|
data/lib/active_shard/scope.rb
CHANGED
@@ -33,8 +33,12 @@ module ActiveShard
|
|
33
33
|
# eg: scope.push( :directory => :dir1, :user_data => :db1 )
|
34
34
|
#
|
35
35
|
# @param [Hash] active_shards
|
36
|
+
# @return [Scope::Memento] memento object to pass back to pop() to
|
37
|
+
# revert scope state.
|
36
38
|
#
|
37
39
|
def push( active_shards )
|
40
|
+
previous_state_memento = to_memento()
|
41
|
+
|
38
42
|
scope_crumbs << active_shards
|
39
43
|
|
40
44
|
# shortcutting #build_current_shards for performance reasons
|
@@ -44,10 +48,11 @@ module ActiveShard
|
|
44
48
|
current_shards[schema] = active_shards
|
45
49
|
end
|
46
50
|
current_shards[AnyShard] = active_shards
|
47
|
-
|
48
51
|
else
|
49
52
|
current_shards.merge!( normalize_keys( active_shards ) )
|
50
53
|
end
|
54
|
+
|
55
|
+
previous_state_memento
|
51
56
|
end
|
52
57
|
|
53
58
|
# Remove the last scope from the stack
|
@@ -55,16 +60,14 @@ module ActiveShard
|
|
55
60
|
# FIXME: Symbols (for AnySchema) may not roll back properly if multiple
|
56
61
|
# the same symbol is on the stack several times
|
57
62
|
#
|
58
|
-
def pop(
|
59
|
-
if
|
63
|
+
def pop( memento=nil )
|
64
|
+
if memento.nil?
|
60
65
|
scope_crumbs.pop
|
66
|
+
|
67
|
+
build_current_shards( scope_crumbs )
|
61
68
|
else
|
62
|
-
(
|
63
|
-
scope_crumbs.pop
|
64
|
-
end
|
69
|
+
restore_from_memento!( memento )
|
65
70
|
end
|
66
|
-
|
67
|
-
build_current_shards( scope_crumbs )
|
68
71
|
end
|
69
72
|
|
70
73
|
# Returns the name of the active shard by the provided schema name.
|
@@ -115,7 +118,25 @@ module ActiveShard
|
|
115
118
|
ret
|
116
119
|
end
|
117
120
|
|
121
|
+
def to_memento
|
122
|
+
Memento.new( scope_crumbs, current_shards )
|
123
|
+
end
|
124
|
+
|
125
|
+
def restore_from_memento!( memento )
|
126
|
+
@scope_crumbs = memento.scope_crumbs
|
127
|
+
@current_shards = memento.current_shards
|
128
|
+
end
|
129
|
+
|
118
130
|
class AnyShard; end
|
119
131
|
|
132
|
+
class Memento
|
133
|
+
attr_reader :scope_crumbs, :current_shards
|
134
|
+
|
135
|
+
def initialize( scope_crumbs, current_shards )
|
136
|
+
@scope_crumbs = scope_crumbs.dup
|
137
|
+
@current_shards = current_shards.dup
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
120
141
|
end
|
121
142
|
end
|
data/lib/active_shard/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: active_shard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Brasten Sager
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-
|
14
|
+
date: 2011-09-02 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|