active_shard 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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/active_record/railtie'
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 = nil
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( scopes )
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
- "#{schema_name.to_s}+#{shard_name.to_s}".to_sym
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
@@ -17,6 +17,12 @@ module ActiveShard
17
17
  shard_definition.connection_spec
18
18
  end
19
19
 
20
+ ##### non-connection_spec related methods #####
21
+
22
+ def shard_name
23
+ shard_definition.name
24
+ end
25
+
20
26
  private
21
27
 
22
28
  attr_reader :shard_definition
@@ -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( pop_until=nil )
59
- if pop_until.nil?
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
- (scope_crumbs.size - scope_crumbs.index(pop_until)).times do
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
@@ -1,3 +1,3 @@
1
1
  module ActiveShard
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
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.0
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-08-19 00:00:00 Z
14
+ date: 2011-09-02 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport