switchman 3.0.9 → 3.1.0

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/lib/switchman/action_controller/caching.rb +2 -2
  4. data/lib/switchman/active_record/abstract_adapter.rb +2 -4
  5. data/lib/switchman/active_record/associations.rb +223 -0
  6. data/lib/switchman/active_record/attribute_methods.rb +144 -84
  7. data/lib/switchman/active_record/base.rb +71 -31
  8. data/lib/switchman/active_record/calculations.rb +11 -4
  9. data/lib/switchman/active_record/connection_pool.rb +2 -4
  10. data/lib/switchman/active_record/database_configurations.rb +18 -2
  11. data/lib/switchman/active_record/finder_methods.rb +2 -2
  12. data/lib/switchman/active_record/model_schema.rb +1 -1
  13. data/lib/switchman/active_record/persistence.rb +3 -5
  14. data/lib/switchman/active_record/postgresql_adapter.rb +1 -1
  15. data/lib/switchman/active_record/query_methods.rb +20 -11
  16. data/lib/switchman/active_record/reflection.rb +1 -1
  17. data/lib/switchman/active_record/relation.rb +15 -18
  18. data/lib/switchman/active_record/statement_cache.rb +2 -2
  19. data/lib/switchman/active_record/table_definition.rb +1 -1
  20. data/lib/switchman/active_support/cache.rb +16 -0
  21. data/lib/switchman/database_server.rb +26 -18
  22. data/lib/switchman/default_shard.rb +0 -2
  23. data/lib/switchman/engine.rb +63 -125
  24. data/lib/switchman/errors.rb +4 -2
  25. data/lib/switchman/guard_rail/relation.rb +6 -9
  26. data/lib/switchman/guard_rail.rb +5 -0
  27. data/lib/switchman/parallel.rb +68 -0
  28. data/lib/switchman/r_spec_helper.rb +3 -0
  29. data/lib/switchman/rails.rb +2 -5
  30. data/{app/models → lib}/switchman/shard.rb +28 -133
  31. data/lib/switchman/sharded_instrumenter.rb +1 -1
  32. data/lib/switchman/standard_error.rb +10 -11
  33. data/{app/models → lib}/switchman/unsharded_record.rb +1 -1
  34. data/lib/switchman/version.rb +1 -1
  35. data/lib/switchman.rb +22 -2
  36. data/lib/tasks/switchman.rake +16 -9
  37. metadata +20 -20
  38. data/lib/switchman/active_record/association.rb +0 -206
  39. data/lib/switchman/open4.rb +0 -80
@@ -8,15 +8,12 @@ module Switchman
8
8
 
9
9
  class << self
10
10
  attr_accessor :creating_new_shard
11
+ attr_reader :all_roles
11
12
 
12
13
  def all
13
14
  database_servers.values
14
15
  end
15
16
 
16
- def all_roles
17
- @all_roles ||= all.map(&:roles).flatten.uniq
18
- end
19
-
20
17
  def find(id_or_all)
21
18
  return all if id_or_all == :all
22
19
  return id_or_all.map { |id| database_servers[id || ::Rails.env] }.compact.uniq if id_or_all.is_a?(Array)
@@ -38,7 +35,7 @@ module Switchman
38
35
  database_servers[server.id] = server
39
36
  ::ActiveRecord::Base.configurations.configurations <<
40
37
  ::ActiveRecord::DatabaseConfigurations::HashConfig.new(::Rails.env, "#{server.id}/primary", settings)
41
- Shard.send(:initialize_sharding)
38
+ Shard.send(:configure_connects_to)
42
39
  server
43
40
  end
44
41
 
@@ -49,31 +46,42 @@ module Switchman
49
46
  servers[rand(servers.length)]
50
47
  end
51
48
 
49
+ def guard_servers
50
+ all.each { |db| db.guard! if db.config[:prefer_secondary] }
51
+ end
52
+
52
53
  private
53
54
 
54
55
  def reference_role(role)
55
56
  return if all_roles.include?(role)
56
57
 
57
58
  @all_roles << role
58
- Shard.send(:initialize_sharding)
59
+ Shard.send(:configure_connects_to)
59
60
  end
60
61
 
61
62
  def database_servers
62
63
  if !@database_servers || @database_servers.empty?
63
64
  @database_servers = {}.with_indifferent_access
65
+ roles = []
64
66
  ::ActiveRecord::Base.configurations.configurations.each do |config|
65
67
  if config.name.include?('/')
66
68
  name, role = config.name.split('/')
67
69
  else
68
70
  name, role = config.env_name, config.name
69
71
  end
72
+ role = role.to_sym
70
73
 
71
- if role == 'primary'
74
+ roles << role
75
+ if role == :primary
72
76
  @database_servers[name] = DatabaseServer.new(config.env_name, config.configuration_hash)
73
77
  else
74
78
  @database_servers[name].roles << role
75
79
  end
76
80
  end
81
+ # Do this after so that all database servers for all roles are established and we won't prematurely
82
+ # configure a connection for the wrong role
83
+ @all_roles = roles.uniq
84
+ Shard.send(:configure_connects_to)
77
85
  end
78
86
  @database_servers
79
87
  end
@@ -129,27 +137,27 @@ module Switchman
129
137
  end
130
138
  end
131
139
 
132
- def guard_rail_environment
133
- @guard_rail_environment || ::GuardRail.environment
134
- end
135
-
136
140
  # locks this db to a specific environment, except for
137
141
  # when doing writes (then it falls back to the current
138
142
  # value of GuardRail.environment)
139
143
  def guard!(environment = :secondary)
140
- @guard_rail_environment = environment
144
+ DatabaseServer.send(:reference_role, environment)
145
+ ::ActiveRecord::Base.connected_to_stack << { shard_roles: { id.to_sym => environment }, klasses: [::ActiveRecord::Base] }
141
146
  end
142
147
 
143
148
  def unguard!
144
- @guard_rail_environment = nil
149
+ ::ActiveRecord::Base.connected_to_stack << { shard_roles: { id.to_sym => :_switchman_inherit }, klasses: [::ActiveRecord::Base] }
145
150
  end
146
151
 
147
152
  def unguard
148
- old_env = @guard_rail_environment
149
- unguard!
150
- yield
151
- ensure
152
- guard!(old_env)
153
+ return yield unless ::ActiveRecord::Base.role_overriden?(id.to_sym)
154
+
155
+ begin
156
+ unguard!
157
+ yield
158
+ ensure
159
+ ::ActiveRecord::Base.connected_to_stack.pop
160
+ end
153
161
  end
154
162
 
155
163
  def shards
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'switchman/database_server'
4
-
5
3
  module Switchman
6
4
  class DefaultShard
7
5
  def id
@@ -8,102 +8,27 @@ module Switchman
8
8
  config.active_record.legacy_connection_handling = false
9
9
  config.active_record.writing_role = :primary
10
10
 
11
- config.autoload_once_paths << File.expand_path('app/models', config.paths.path)
11
+ ::GuardRail.singleton_class.prepend(GuardRail::ClassMethods)
12
12
 
13
- def self.lookup_stores(cache_store_config)
14
- result = {}
15
- cache_store_config.each do |key, value|
16
- next if value.is_a?(String)
17
-
18
- result[key] = ::ActiveSupport::Cache.lookup_store(value)
19
- end
20
-
21
- cache_store_config.each do |key, value| # rubocop:disable Style/CombinableLoops
22
- next unless value.is_a?(String)
23
-
24
- result[key] = result[value]
25
- end
26
- result
27
- end
28
-
29
- initializer 'switchman.initialize_cache', before: 'initialize_cache' do
30
- require 'switchman/active_support/cache'
31
- ::ActiveSupport::Cache.singleton_class.prepend(ActiveSupport::Cache::ClassMethods)
32
-
33
- # if we haven't already setup our cache map out-of-band, set it up from
34
- # config.cache_store now. behaves similarly to Rails' default
35
- # initialize_cache initializer, but for each value in the map, rather
36
- # than just Rails.cache. if config.cache_store is a flat value, uses it
37
- # to fill just the Rails.env entry in the cache map.
38
- unless Switchman.config[:cache_map].present?
39
- cache_store_config = ::Rails.configuration.cache_store
40
- cache_store_config = { ::Rails.env => cache_store_config } unless cache_store_config.is_a?(Hash)
41
-
42
- Switchman.config[:cache_map] = Engine.lookup_stores(cache_store_config)
43
- end
44
-
45
- # if the configured cache map (either from before, or as populated from
46
- # config.cache_store) didn't have an entry for Rails.env, add one using
47
- # lookup_store(nil); matches the behavior of Rails' default
48
- # initialize_cache initializer when config.cache_store is nil.
49
- unless Switchman.config[:cache_map].key?(::Rails.env)
50
- value = ::ActiveSupport::Cache.lookup_store(nil)
51
- Switchman.config[:cache_map][::Rails.env] = value
52
- end
53
-
54
- middlewares = Switchman.config[:cache_map].values.map do |store|
55
- store.middleware if store.respond_to?(:middleware)
56
- end.compact.uniq
57
- middlewares.each do |middleware|
58
- config.middleware.insert_before('Rack::Runtime', middleware)
59
- end
60
-
61
- # prevent :initialize_cache from trying to (or needing to) set
62
- # Rails.cache. once our switchman.extend_ar initializer (below) runs
63
- # Rails.cache will be overridden to pull appropriate values from the
64
- # cache map, but between now and then, Rails.cache should return the
65
- # Rails.env entry in the cache map.
66
- ::Rails.cache = Switchman.config[:cache_map][::Rails.env]
13
+ # after :initialize_dependency_mechanism to ensure autoloading is configured for any downstream initializers that care
14
+ # In rails 7.0 we should be able to just use an explicit after on configuring the once autoloaders and not need to go monkey around with initializer order
15
+ if ::Rails.version < '7.0'
16
+ initialize_dependency_mechanism = ::Rails::Application::Bootstrap.initializers.find { |i| i.name == :initialize_dependency_mechanism }
17
+ initialize_dependency_mechanism.instance_variable_get(:@options)[:after] = :set_autoload_paths
67
18
  end
68
19
 
69
- initializer 'switchman.extend_ar', before: 'active_record.initialize_database' do
20
+ initializer 'switchman.active_record_patch',
21
+ before: 'active_record.initialize_database',
22
+ after: (::Rails.version < '7.0' ? :initialize_dependency_mechanism : :setup_once_autoloader) do
70
23
  ::ActiveSupport.on_load(:active_record) do
71
- require 'switchman/active_record/abstract_adapter'
72
- require 'switchman/active_record/association'
73
- require 'switchman/active_record/attribute_methods'
74
- require 'switchman/active_record/base'
75
- require 'switchman/active_record/calculations'
76
- require 'switchman/active_record/connection_pool'
77
- require 'switchman/active_record/database_configurations'
78
- require 'switchman/active_record/database_configurations/database_config'
79
- require 'switchman/active_record/finder_methods'
80
- require 'switchman/active_record/log_subscriber'
81
- require 'switchman/active_record/migration'
82
- require 'switchman/active_record/model_schema'
83
- require 'switchman/active_record/persistence'
84
- require 'switchman/active_record/predicate_builder'
85
- require 'switchman/active_record/query_cache'
86
- require 'switchman/active_record/query_methods'
87
- require 'switchman/active_record/reflection'
88
- require 'switchman/active_record/relation'
89
- require 'switchman/active_record/spawn_methods'
90
- require 'switchman/active_record/statement_cache'
91
- require 'switchman/active_record/tasks/database_tasks'
92
- require 'switchman/active_record/type_caster'
93
- require 'switchman/active_record/test_fixtures'
94
- require 'switchman/arel'
95
- require 'switchman/call_super'
96
- require 'switchman/rails'
97
- require 'switchman/guard_rail/relation'
98
- require 'switchman/standard_error'
99
-
100
- ::StandardError.include(StandardError)
24
+ # Switchman requires postgres, so just always load the pg adapter
25
+ require 'active_record/connection_adapters/postgresql_adapter'
101
26
 
102
27
  self.default_shard = ::Rails.env.to_sym
103
28
  self.default_role = :primary
104
29
 
105
30
  prepend ActiveRecord::Base
106
- include ActiveRecord::AttributeMethods
31
+ prepend ActiveRecord::AttributeMethods
107
32
  include ActiveRecord::Persistence
108
33
  singleton_class.prepend ActiveRecord::ModelSchema::ClassMethods
109
34
 
@@ -112,22 +37,24 @@ module Switchman
112
37
  ::ActiveRecord::StatementCache::BindMap.prepend(ActiveRecord::StatementCache::BindMap)
113
38
  ::ActiveRecord::StatementCache::Substitute.send(:attr_accessor, :primary, :sharded)
114
39
 
115
- ::ActiveRecord::Associations::CollectionAssociation.prepend(ActiveRecord::CollectionAssociation)
116
- ::ActiveRecord::Associations::HasOneAssociation.prepend(ActiveRecord::ForeignAssociation)
117
- ::ActiveRecord::Associations::HasManyAssociation.prepend(ActiveRecord::ForeignAssociation)
40
+ ::ActiveRecord::Associations::CollectionAssociation.prepend(ActiveRecord::Associations::CollectionAssociation)
41
+ ::ActiveRecord::Associations::HasOneAssociation.prepend(ActiveRecord::Associations::ForeignAssociation)
42
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(ActiveRecord::Associations::ForeignAssociation)
118
43
 
119
44
  ::ActiveRecord::PredicateBuilder.singleton_class.prepend(ActiveRecord::PredicateBuilder)
120
45
 
121
- prepend(ActiveRecord::AutosaveAssociation)
46
+ prepend(ActiveRecord::Associations::AutosaveAssociation)
122
47
 
123
- ::ActiveRecord::Associations::Association.prepend(ActiveRecord::Association)
124
- ::ActiveRecord::Associations::BelongsToAssociation.prepend(ActiveRecord::BelongsToAssociation)
125
- ::ActiveRecord::Associations::CollectionProxy.include(ActiveRecord::CollectionProxy)
48
+ ::ActiveRecord::Associations::Association.prepend(ActiveRecord::Associations::Association)
49
+ ::ActiveRecord::Associations::BelongsToAssociation.prepend(ActiveRecord::Associations::BelongsToAssociation)
50
+ ::ActiveRecord::Associations::CollectionProxy.include(ActiveRecord::Associations::CollectionProxy)
126
51
 
127
- ::ActiveRecord::Associations::Preloader::Association.prepend(ActiveRecord::Preloader::Association)
52
+ ::ActiveRecord::Associations::Preloader::Association.prepend(ActiveRecord::Associations::Preloader::Association)
53
+ ::ActiveRecord::Associations::Preloader::Association::LoaderQuery.prepend(ActiveRecord::Associations::Preloader::Association::LoaderQuery) unless ::Rails.version < '7.0'
128
54
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::AbstractAdapter)
129
55
  ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecord::ConnectionPool)
130
56
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::QueryCache)
57
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
131
58
 
132
59
  ::ActiveRecord::DatabaseConfigurations.prepend(ActiveRecord::DatabaseConfigurations)
133
60
  ::ActiveRecord::DatabaseConfigurations::DatabaseConfig.prepend(ActiveRecord::DatabaseConfigurations::DatabaseConfig)
@@ -160,54 +87,65 @@ module Switchman
160
87
  ::ActiveRecord::TypeCaster::Map.include(ActiveRecord::TypeCaster::Map)
161
88
  ::ActiveRecord::TypeCaster::Connection.include(ActiveRecord::TypeCaster::Connection)
162
89
 
163
- ::Rails.singleton_class.prepend(Rails::ClassMethods)
164
-
165
90
  ::Arel::Table.prepend(Arel::Table)
166
91
  ::Arel::Visitors::ToSql.prepend(Arel::Visitors::ToSql)
167
- end
168
- end
169
-
170
- def self.foreign_key_check(name, type, limit: nil)
171
- puts "WARNING: All foreign keys need to be 8-byte integers. #{name} looks like a foreign key. If so, please add the option: `:limit => 8`" if name.to_s =~ /_id\z/ && type.to_s == 'integer' && limit.to_i < 8
172
- end
173
92
 
174
- initializer 'switchman.extend_connection_adapters', after: 'active_record.initialize_database' do
175
- ::ActiveSupport.on_load(:active_record) do
176
93
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.descendants.each do |klass|
177
94
  klass.prepend(ActiveRecord::AbstractAdapter::ForeignKeyCheck)
178
95
  end
179
96
 
180
- require 'switchman/active_record/table_definition'
181
97
  ::ActiveRecord::ConnectionAdapters::TableDefinition.prepend(ActiveRecord::TableDefinition)
182
-
183
- if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
184
- require 'switchman/active_record/postgresql_adapter'
185
- ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
186
- end
187
-
188
- Shard.send(:initialize_sharding)
189
98
  end
99
+ # Ensure that ActiveRecord::Base is always loaded before any app-level initializers can go try to load Switchman::Shard or we get a loop
100
+ ::ActiveRecord::Base
190
101
  end
191
102
 
192
- initializer 'switchman.eager_load' do
193
- ::ActiveSupport.on_load(:before_eager_load) do
194
- # This needs to be loaded before Switchman::Shard, otherwise it won't autoload it correctly
195
- require 'active_record/base'
103
+ initializer 'switchman.error_patch', after: 'active_record.initialize_database' do
104
+ ::ActiveSupport.on_load(:active_record) do
105
+ ::StandardError.include(StandardError)
196
106
  end
197
107
  end
198
108
 
199
- initializer 'switchman.extend_guard_rail', before: 'switchman.extend_ar' do
200
- ::ActiveSupport.on_load(:active_record) do
201
- require 'switchman/guard_rail'
109
+ initializer 'switchman.initialize_cache', before: :initialize_cache, after: 'active_record.initialize_database' do
110
+ ::ActiveSupport::Cache.singleton_class.prepend(ActiveSupport::Cache::ClassMethods)
202
111
 
203
- ::GuardRail.singleton_class.prepend(GuardRail::ClassMethods)
112
+ # if we haven't already setup our cache map out-of-band, set it up from
113
+ # config.cache_store now. behaves similarly to Rails' default
114
+ # initialize_cache initializer, but for each value in the map, rather
115
+ # than just Rails.cache. if config.cache_store is a flat value, uses it
116
+ # to fill just the Rails.env entry in the cache map.
117
+ unless Switchman.config[:cache_map].present?
118
+ cache_store_config = ::Rails.configuration.cache_store
119
+ cache_store_config = { ::Rails.env => cache_store_config } unless cache_store_config.is_a?(Hash)
120
+
121
+ Switchman.config[:cache_map] = ::ActiveSupport::Cache.lookup_stores(cache_store_config)
204
122
  end
205
- end
206
123
 
207
- initializer 'switchman.extend_controller', after: 'guard_rail.extend_ar' do
208
- ::ActiveSupport.on_load(:action_controller) do
209
- require 'switchman/action_controller/caching'
124
+ # if the configured cache map (either from before, or as populated from
125
+ # config.cache_store) didn't have an entry for Rails.env, add one using
126
+ # lookup_store(nil); matches the behavior of Rails' default
127
+ # initialize_cache initializer when config.cache_store is nil.
128
+ unless Switchman.config[:cache_map].key?(::Rails.env)
129
+ value = ::ActiveSupport::Cache.lookup_store(nil)
130
+ Switchman.config[:cache_map][::Rails.env] = value
131
+ end
132
+
133
+ middlewares = Switchman.config[:cache_map].values.map do |store|
134
+ store.middleware if store.respond_to?(:middleware)
135
+ end.compact.uniq
136
+ middlewares.each do |middleware|
137
+ config.middleware.insert_before('Rack::Runtime', middleware)
138
+ end
210
139
 
140
+ # prevent :initialize_cache from trying to (or needing to) set
141
+ # Rails.cache. once our switchman.extend_ar initializer (below) runs
142
+ # Rails.cache will be overridden to pull appropriate values from the
143
+ # cache map, but between now and then, Rails.cache should return the
144
+ # Rails.env entry in the cache map.
145
+ ::Rails.cache = Switchman.config[:cache_map][::Rails.env]
146
+ ::Rails.singleton_class.prepend(Rails::ClassMethods)
147
+
148
+ ::ActiveSupport.on_load(:action_controller) do
211
149
  ::ActionController::Base.include(ActionController::Caching)
212
150
  end
213
151
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Switchman
4
- class NonExistentShardError < RuntimeError; end
4
+ module Errors
5
+ class NonExistentShardError < RuntimeError; end
5
6
 
6
- class ParallelShardExecError < RuntimeError; end
7
+ class ParallelShardExecError < RuntimeError; end
8
+ end
7
9
  end
@@ -5,21 +5,18 @@ module Switchman
5
5
  module Relation
6
6
  def exec_queries(*args)
7
7
  if lock_value
8
- db = Shard.current(connection_classes).database_server
9
- return db.unguard { super } if ::GuardRail.environment != db.guard_rail_environment
8
+ db = Shard.current(connection_class_for_self).database_server
9
+ db.unguard { super }
10
+ else
11
+ super
10
12
  end
11
- super
12
13
  end
13
14
 
14
15
  %w[update_all delete_all].each do |method|
15
16
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
16
17
  def #{method}(*args)
17
- db = Shard.current(connection_classes).database_server
18
- if ::GuardRail.environment != db.guard_rail_environment
19
- db.unguard { super }
20
- else
21
- super
22
- end
18
+ db = Shard.current(connection_class_for_self).database_server
19
+ db.unguard { super }
23
20
  end
24
21
  RUBY
25
22
  end
@@ -3,6 +3,11 @@
3
3
  module Switchman
4
4
  module GuardRail
5
5
  module ClassMethods
6
+ def environment
7
+ # no overrides so we get the global role, not the role for the default shard
8
+ ::ActiveRecord::Base.current_role(without_overrides: true)
9
+ end
10
+
6
11
  def activate(role)
7
12
  DatabaseServer.send(:reference_role, role)
8
13
  super
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parallel'
4
+
5
+ module Switchman
6
+ module Parallel
7
+ module UndumpableException
8
+ def initialize(original)
9
+ super
10
+ @active_shards = original.instance_variable_get(:@active_shards)
11
+ current_shard
12
+ end
13
+ end
14
+
15
+ class QuietExceptionWrapper
16
+ attr_accessor :name
17
+
18
+ def initialize(name, wrapper)
19
+ @name = name
20
+ @wrapper = wrapper
21
+ end
22
+
23
+ def exception
24
+ @wrapper.exception
25
+ end
26
+ end
27
+
28
+ class UndumpableResult
29
+ attr_reader :name
30
+
31
+ def initialize(result)
32
+ @name = result.inspect
33
+ end
34
+
35
+ def inspect
36
+ "#<UndumpableResult:#{name}>"
37
+ end
38
+ end
39
+
40
+ class ResultWrapper
41
+ attr_reader :result
42
+
43
+ def initialize(result)
44
+ @result =
45
+ begin
46
+ Marshal.dump(result) && result
47
+ rescue
48
+ UndumpableResult.new(result)
49
+ end
50
+ end
51
+ end
52
+
53
+ class PrefixingIO
54
+ delegate_missing_to :@original_io
55
+
56
+ def initialize(prefix, original_io)
57
+ @prefix = prefix
58
+ @original_io = original_io
59
+ end
60
+
61
+ def puts(*args)
62
+ args.flatten.each { |arg| @original_io.puts "#{@prefix}: #{arg}" }
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ ::Parallel::UndumpableException.prepend(::Switchman::Parallel::UndumpableException)
@@ -70,7 +70,10 @@ module Switchman
70
70
  Shard.default(reload: true)
71
71
  puts 'Done!'
72
72
 
73
+ main_pid = Process.pid
73
74
  at_exit do
75
+ next unless main_pid == Process.pid
76
+
74
77
  # preserve rspec's exit status
75
78
  status = $!.is_a?(::SystemExit) ? $!.status : nil
76
79
  puts 'Tearing down sharding for all specs'
@@ -4,16 +4,13 @@ module Switchman
4
4
  module Rails
5
5
  module ClassMethods
6
6
  def self.prepended(klass)
7
- # in Rails 4+, the Rails.cache= method was used during bootstrap to set
8
- # Rails.cache(_without_sharding) to the value from the config file. but now
9
- # that that's done (the bootstrap happened before this module is included
10
- # into Rails), we want to make sure no one tries to assign to Rails.cache,
7
+ # we want to make sure no one tries to assign to Rails.cache,
11
8
  # because it would be wrong w.r.t. sharding.
12
9
  klass.send(:remove_method, :cache=)
13
10
  end
14
11
 
15
12
  def cache
16
- Switchman::Shard.current ? Switchman::Shard.current.database_server.cache_store : super
13
+ Switchman::Shard.current.database_server.cache_store
17
14
  end
18
15
  end
19
16
  end