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/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