switchman 2.0.13 → 3.0.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +10 -2
  3. data/app/models/switchman/shard.rb +234 -271
  4. data/app/models/switchman/unsharded_record.rb +7 -0
  5. data/db/migrate/20130328212039_create_switchman_shards.rb +1 -1
  6. data/db/migrate/20130328224244_create_default_shard.rb +5 -5
  7. data/db/migrate/20161206323434_add_back_default_string_limits_switchman.rb +1 -0
  8. data/db/migrate/20180828183945_add_default_shard_index.rb +2 -2
  9. data/db/migrate/20180828192111_add_timestamps_to_shards.rb +7 -5
  10. data/db/migrate/20190114212900_add_unique_name_indexes.rb +5 -3
  11. data/lib/switchman.rb +3 -5
  12. data/lib/switchman/action_controller/caching.rb +2 -2
  13. data/lib/switchman/active_record/abstract_adapter.rb +1 -0
  14. data/lib/switchman/active_record/association.rb +78 -89
  15. data/lib/switchman/active_record/attribute_methods.rb +58 -52
  16. data/lib/switchman/active_record/base.rb +58 -59
  17. data/lib/switchman/active_record/calculations.rb +74 -67
  18. data/lib/switchman/active_record/connection_pool.rb +14 -41
  19. data/lib/switchman/active_record/database_configurations.rb +34 -0
  20. data/lib/switchman/active_record/database_configurations/database_config.rb +13 -0
  21. data/lib/switchman/active_record/finder_methods.rb +11 -16
  22. data/lib/switchman/active_record/log_subscriber.rb +4 -8
  23. data/lib/switchman/active_record/migration.rb +6 -47
  24. data/lib/switchman/active_record/model_schema.rb +1 -1
  25. data/lib/switchman/active_record/persistence.rb +4 -6
  26. data/lib/switchman/active_record/postgresql_adapter.rb +124 -168
  27. data/lib/switchman/active_record/predicate_builder.rb +2 -2
  28. data/lib/switchman/active_record/query_cache.rb +18 -19
  29. data/lib/switchman/active_record/query_methods.rb +172 -197
  30. data/lib/switchman/active_record/reflection.rb +6 -10
  31. data/lib/switchman/active_record/relation.rb +30 -78
  32. data/lib/switchman/active_record/spawn_methods.rb +27 -29
  33. data/lib/switchman/active_record/statement_cache.rb +18 -35
  34. data/lib/switchman/active_record/tasks/database_tasks.rb +16 -0
  35. data/lib/switchman/active_support/cache.rb +3 -5
  36. data/lib/switchman/arel.rb +13 -8
  37. data/lib/switchman/database_server.rb +121 -142
  38. data/lib/switchman/default_shard.rb +52 -16
  39. data/lib/switchman/engine.rb +61 -58
  40. data/lib/switchman/environment.rb +4 -8
  41. data/lib/switchman/errors.rb +1 -0
  42. data/lib/switchman/guard_rail.rb +6 -19
  43. data/lib/switchman/guard_rail/relation.rb +5 -7
  44. data/lib/switchman/r_spec_helper.rb +29 -37
  45. data/lib/switchman/rails.rb +14 -12
  46. data/lib/switchman/schema_cache.rb +1 -9
  47. data/lib/switchman/sharded_instrumenter.rb +1 -1
  48. data/lib/switchman/standard_error.rb +15 -3
  49. data/lib/switchman/test_helper.rb +7 -11
  50. data/lib/switchman/version.rb +1 -1
  51. data/lib/tasks/switchman.rake +54 -69
  52. metadata +87 -45
  53. data/lib/switchman/active_record/batches.rb +0 -11
  54. data/lib/switchman/active_record/connection_handler.rb +0 -172
  55. data/lib/switchman/active_record/where_clause_factory.rb +0 -36
  56. data/lib/switchman/connection_pool_proxy.rb +0 -173
@@ -4,24 +4,30 @@ module Switchman
4
4
  class Engine < ::Rails::Engine
5
5
  isolate_namespace Switchman
6
6
 
7
- config.autoload_once_paths << File.expand_path("app/models", config.paths.path)
7
+ # enable Rails 6.1 style connection handling
8
+ config.active_record.legacy_connection_handling = false
9
+ config.active_record.writing_role = :primary
10
+
11
+ config.autoload_once_paths << File.expand_path('app/models', config.paths.path)
8
12
 
9
13
  def self.lookup_stores(cache_store_config)
10
14
  result = {}
11
15
  cache_store_config.each do |key, value|
12
16
  next if value.is_a?(String)
17
+
13
18
  result[key] = ::ActiveSupport::Cache.lookup_store(value)
14
19
  end
15
20
 
16
- cache_store_config.each do |key, value|
21
+ cache_store_config.each do |key, value| # rubocop:disable Style/CombinableLoops
17
22
  next unless value.is_a?(String)
23
+
18
24
  result[key] = result[value]
19
25
  end
20
26
  result
21
27
  end
22
28
 
23
- initializer 'switchman.initialize_cache', :before => 'initialize_cache' do
24
- require "switchman/active_support/cache"
29
+ initializer 'switchman.initialize_cache', before: 'initialize_cache' do
30
+ require 'switchman/active_support/cache'
25
31
  ::ActiveSupport::Cache.singleton_class.prepend(ActiveSupport::Cache::ClassMethods)
26
32
 
27
33
  # if we haven't already setup our cache map out-of-band, set it up from
@@ -31,9 +37,7 @@ module Switchman
31
37
  # to fill just the Rails.env entry in the cache map.
32
38
  unless Switchman.config[:cache_map].present?
33
39
  cache_store_config = ::Rails.configuration.cache_store
34
- unless cache_store_config.is_a?(Hash)
35
- cache_store_config = {::Rails.env => cache_store_config}
36
- end
40
+ cache_store_config = { ::Rails.env => cache_store_config } unless cache_store_config.is_a?(Hash)
37
41
 
38
42
  Switchman.config[:cache_map] = Engine.lookup_stores(cache_store_config)
39
43
  end
@@ -42,7 +46,7 @@ module Switchman
42
46
  # config.cache_store) didn't have an entry for Rails.env, add one using
43
47
  # lookup_store(nil); matches the behavior of Rails' default
44
48
  # initialize_cache initializer when config.cache_store is nil.
45
- unless Switchman.config[:cache_map].has_key?(::Rails.env)
49
+ unless Switchman.config[:cache_map].key?(::Rails.env)
46
50
  value = ::ActiveSupport::Cache.lookup_store(nil)
47
51
  Switchman.config[:cache_map][::Rails.env] = value
48
52
  end
@@ -51,7 +55,7 @@ module Switchman
51
55
  store.middleware if store.respond_to?(:middleware)
52
56
  end.compact.uniq
53
57
  middlewares.each do |middleware|
54
- config.middleware.insert_before("Rack::Runtime", middleware)
58
+ config.middleware.insert_before('Rack::Runtime', middleware)
55
59
  end
56
60
 
57
61
  # prevent :initialize_cache from trying to (or needing to) set
@@ -62,39 +66,41 @@ module Switchman
62
66
  ::Rails.cache = Switchman.config[:cache_map][::Rails.env]
63
67
  end
64
68
 
65
- initializer 'switchman.extend_ar', :before => "active_record.initialize_database" do
69
+ initializer 'switchman.extend_ar', before: 'active_record.initialize_database' do
66
70
  ::ActiveSupport.on_load(:active_record) do
67
- require "switchman/active_record/abstract_adapter"
68
- require "switchman/active_record/association"
69
- require "switchman/active_record/attribute_methods"
70
- require "switchman/active_record/base"
71
- require "switchman/active_record/batches"
72
- require "switchman/active_record/calculations"
73
- require "switchman/active_record/connection_handler"
74
- require "switchman/active_record/connection_pool"
75
- require "switchman/active_record/finder_methods"
76
- require "switchman/active_record/log_subscriber"
77
- require "switchman/active_record/migration"
78
- require "switchman/active_record/model_schema"
79
- require "switchman/active_record/persistence"
80
- require "switchman/active_record/predicate_builder"
81
- require "switchman/active_record/query_cache"
82
- require "switchman/active_record/query_methods"
83
- require "switchman/active_record/reflection"
84
- require "switchman/active_record/relation"
85
- require "switchman/active_record/spawn_methods"
86
- require "switchman/active_record/statement_cache"
87
- require "switchman/active_record/type_caster"
88
- require "switchman/active_record/where_clause_factory"
89
- require "switchman/arel"
90
- require "switchman/call_super"
91
- require "switchman/rails"
92
- require "switchman/guard_rail/relation"
93
- require_dependency "switchman/shard"
94
- require "switchman/standard_error"
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/arel'
94
+ require 'switchman/call_super'
95
+ require 'switchman/rails'
96
+ require 'switchman/guard_rail/relation'
97
+ require 'switchman/standard_error'
95
98
 
96
99
  ::StandardError.include(StandardError)
97
100
 
101
+ self.default_shard = ::Rails.env.to_sym
102
+ self.default_role = :primary
103
+
98
104
  include ActiveRecord::Base
99
105
  include ActiveRecord::AttributeMethods
100
106
  include ActiveRecord::Persistence
@@ -106,6 +112,8 @@ module Switchman
106
112
  ::ActiveRecord::StatementCache::Substitute.send(:attr_accessor, :primary, :sharded)
107
113
 
108
114
  ::ActiveRecord::Associations::CollectionAssociation.prepend(ActiveRecord::CollectionAssociation)
115
+ ::ActiveRecord::Associations::HasOneAssociation.prepend(ActiveRecord::ForeignAssociation)
116
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(ActiveRecord::ForeignAssociation)
109
117
 
110
118
  ::ActiveRecord::PredicateBuilder.singleton_class.prepend(ActiveRecord::PredicateBuilder)
111
119
 
@@ -117,21 +125,22 @@ module Switchman
117
125
 
118
126
  ::ActiveRecord::Associations::Preloader::Association.prepend(ActiveRecord::Preloader::Association)
119
127
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::AbstractAdapter)
120
- ::ActiveRecord::ConnectionAdapters::ConnectionHandler.prepend(ActiveRecord::ConnectionHandler)
121
128
  ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecord::ConnectionPool)
122
129
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::QueryCache)
123
130
 
131
+ ::ActiveRecord::DatabaseConfigurations.prepend(ActiveRecord::DatabaseConfigurations)
132
+ ::ActiveRecord::DatabaseConfigurations::DatabaseConfig.prepend(ActiveRecord::DatabaseConfigurations::DatabaseConfig)
133
+
124
134
  ::ActiveRecord::LogSubscriber.prepend(ActiveRecord::LogSubscriber)
125
135
  ::ActiveRecord::Migration.prepend(ActiveRecord::Migration)
126
136
  ::ActiveRecord::Migration::Compatibility::V5_0.prepend(ActiveRecord::Migration::Compatibility::V5_0)
127
- ::ActiveRecord::MigrationContext.prepend(ActiveRecord::MigrationContext) if ::Rails.version >= '5.2'
137
+ ::ActiveRecord::MigrationContext.prepend(ActiveRecord::MigrationContext)
128
138
  ::ActiveRecord::Migrator.prepend(ActiveRecord::Migrator)
129
139
 
130
140
  ::ActiveRecord::Reflection::AbstractReflection.include(ActiveRecord::Reflection::AbstractReflection)
131
141
  ::ActiveRecord::Reflection::AssociationReflection.prepend(ActiveRecord::Reflection::AssociationScopeCache)
132
142
  ::ActiveRecord::Reflection::ThroughReflection.prepend(ActiveRecord::Reflection::AssociationScopeCache)
133
143
  ::ActiveRecord::Reflection::AssociationReflection.prepend(ActiveRecord::Reflection::AssociationReflection)
134
- ::ActiveRecord::Relation.prepend(ActiveRecord::Batches)
135
144
  ::ActiveRecord::Relation.prepend(ActiveRecord::Calculations)
136
145
  ::ActiveRecord::Relation.include(ActiveRecord::FinderMethods)
137
146
  ::ActiveRecord::Relation.include(ActiveRecord::QueryMethods)
@@ -140,9 +149,10 @@ module Switchman
140
149
  ::ActiveRecord::Relation.include(ActiveRecord::SpawnMethods)
141
150
  ::ActiveRecord::Relation.include(CallSuper)
142
151
 
143
- ::ActiveRecord::Relation::WhereClauseFactory.prepend(ActiveRecord::WhereClauseFactory)
144
152
  ::ActiveRecord::PredicateBuilder::AssociationQueryValue.prepend(ActiveRecord::PredicateBuilder::AssociationQueryValue)
145
- ::ActiveRecord::PredicateBuilder::PolymorphicArrayValue.prepend(ActiveRecord::PredicateBuilder::AssociationQueryValue)
153
+
154
+ ::ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(ActiveRecord::Tasks::DatabaseTasks)
155
+
146
156
  ::ActiveRecord::TypeCaster::Map.include(ActiveRecord::TypeCaster::Map)
147
157
  ::ActiveRecord::TypeCaster::Connection.include(ActiveRecord::TypeCaster::Connection)
148
158
 
@@ -154,12 +164,10 @@ module Switchman
154
164
  end
155
165
 
156
166
  def self.foreign_key_check(name, type, limit: nil)
157
- if name.to_s =~ /_id\z/ && type.to_s == 'integer' && limit.to_i < 8
158
- 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`"
159
- end
167
+ 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
160
168
  end
161
169
 
162
- initializer 'switchman.extend_connection_adapters', :after => "active_record.initialize_database" do
170
+ initializer 'switchman.extend_connection_adapters', after: 'active_record.initialize_database' do
163
171
  ::ActiveSupport.on_load(:active_record) do
164
172
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.descendants.each do |klass|
165
173
  klass.prepend(ActiveRecord::AbstractAdapter::ForeignKeyCheck)
@@ -169,15 +177,11 @@ module Switchman
169
177
  ::ActiveRecord::ConnectionAdapters::TableDefinition.prepend(ActiveRecord::TableDefinition)
170
178
 
171
179
  if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
172
- require "switchman/active_record/postgresql_adapter"
180
+ require 'switchman/active_record/postgresql_adapter'
173
181
  ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
174
182
  end
175
183
 
176
- # If Switchman::Shard wasn't loaded as of when ActiveRecord::Base initialized
177
- # establish a connection here instead
178
- if !Shard.instance_variable_get(:@default)
179
- ::ActiveRecord::Base.establish_connection
180
- end
184
+ Shard.send(:initialize_sharding)
181
185
  end
182
186
  end
183
187
 
@@ -188,21 +192,20 @@ module Switchman
188
192
  end
189
193
  end
190
194
 
191
- initializer 'switchman.extend_guard_rail', :before => "switchman.extend_ar" do
195
+ initializer 'switchman.extend_guard_rail', before: 'switchman.extend_ar' do
192
196
  ::ActiveSupport.on_load(:active_record) do
193
- require "switchman/guard_rail"
197
+ require 'switchman/guard_rail'
194
198
 
195
199
  ::GuardRail.singleton_class.prepend(GuardRail::ClassMethods)
196
200
  end
197
201
  end
198
202
 
199
- initializer 'switchman.extend_controller', :after => "guard_rail.extend_ar" do
203
+ initializer 'switchman.extend_controller', after: 'guard_rail.extend_ar' do
200
204
  ::ActiveSupport.on_load(:action_controller) do
201
- require "switchman/action_controller/caching"
205
+ require 'switchman/action_controller/caching'
202
206
 
203
207
  ::ActionController::Base.include(ActionController::Caching)
204
208
  end
205
209
  end
206
-
207
210
  end
208
211
  end
@@ -4,17 +4,13 @@ require 'etc'
4
4
 
5
5
  module Switchman
6
6
  class Environment
7
+ def self.cpu_count(nproc_bin = 'nproc')
8
+ return Etc.nprocessors if Etc.respond_to?(:nprocessors)
7
9
 
8
- def self.cpu_count(nproc_bin = "nproc")
9
- if Etc.respond_to?(:nprocessors)
10
- return Etc.nprocessors
11
- end
12
-
13
- return `#{nproc_bin}`.to_i
10
+ `#{nproc_bin}`.to_i
14
11
  rescue Errno::ENOENT
15
12
  # an environment where nproc` isnt available
16
- return 0
13
+ 0
17
14
  end
18
-
19
15
  end
20
16
  end
@@ -2,5 +2,6 @@
2
2
 
3
3
  module Switchman
4
4
  class NonExistentShardError < RuntimeError; end
5
+
5
6
  class ParallelShardExecError < RuntimeError; end
6
7
  end
@@ -3,27 +3,14 @@
3
3
  module Switchman
4
4
  module GuardRail
5
5
  module ClassMethods
6
- def self.prepended(klass)
7
- klass.send(:remove_method, :ensure_handler)
6
+ def activate(role)
7
+ DatabaseServer.send(:reference_role, role)
8
+ super
8
9
  end
9
10
 
10
- # drops the save_handler and ensure_handler calls from the vanilla
11
- # GuardRail' implementation.
12
- def activate!(environment)
13
- environment ||= :primary
14
- activated_environments << environment
15
- old_environment = self.environment
16
- Thread.current[:guard_rail_environment] = environment
17
- old_environment
18
- end
19
-
20
- # since activate! really is just a variable swap now, it's safe to use in
21
- # the ensure block, simplifying the implementation
22
- def activate(environment)
23
- old_environment = activate!(environment)
24
- yield
25
- ensure
26
- activate!(old_environment)
11
+ def activate!(role)
12
+ DatabaseServer.send(:reference_role, role)
13
+ super
27
14
  end
28
15
  end
29
16
  end
@@ -4,19 +4,17 @@ module Switchman
4
4
  module GuardRail
5
5
  module Relation
6
6
  def exec_queries(*args)
7
- if self.lock_value
8
- db = Shard.current(shard_category).database_server
9
- if ::GuardRail.environment != db.guard_rail_environment
10
- return db.unguard { super }
11
- end
7
+ if lock_value
8
+ db = Shard.current(connection_classes).database_server
9
+ return db.unguard { super } if ::GuardRail.environment != db.guard_rail_environment
12
10
  end
13
11
  super
14
12
  end
15
13
 
16
- %w{update_all delete_all}.each do |method|
14
+ %w[update_all delete_all].each do |method|
17
15
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
18
16
  def #{method}(*args)
19
- db = Shard.current(shard_category).database_server
17
+ db = Shard.current(connection_classes).database_server
20
18
  if ::GuardRail.environment != db.guard_rail_environment
21
19
  db.unguard { super }
22
20
  else
@@ -1,16 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "switchman/test_helper"
3
+ require 'switchman/test_helper'
4
4
 
5
5
  module Switchman
6
6
  # including this module in your specs will give you several shards to
7
7
  # work with during specs:
8
8
  # * Shard.default - the test database itself
9
- # * @shard1 - a shard possibly using the same connection as Shard.default
9
+ # * @shard1 - a shard using the same connection as Shard.default
10
10
  # * @shard2 - a shard using a dedicated connection
11
- # * @shard3 - a shard using the same connection as @shard1 (this might
12
- # be Shard.default if they already share a connection, or
13
- # a separate shard)
14
11
  module RSpecHelper
15
12
  @@keep_the_shards = false
16
13
  @@shard1 = nil
@@ -31,14 +28,15 @@ module Switchman
31
28
  root_group.prepend_before(:all) do |group|
32
29
  next if @@shard1
33
30
  next if @@sharding_failed
31
+
34
32
  # if we aren't actually going to run a sharding group/example,
35
33
  # don't set it up after all
36
34
  groups = group.class.descendant_filtered_examples.map(&:example_group).uniq
37
- next unless groups.any?{ |group| RSpecHelper.included_in?(group) }
35
+ next unless groups.any? { |descendant_group| RSpecHelper.included_in?(descendant_group) }
38
36
 
39
- puts "Setting up sharding for all specs..."
37
+ puts 'Setting up sharding for all specs...'
40
38
  Shard.delete_all
41
- Switchman.cache.delete("default_shard")
39
+ Switchman.cache.delete('default_shard')
42
40
 
43
41
  @@shard1, @@shard2 = TestHelper.recreate_persistent_test_shards
44
42
  @@default_shard = Shard.default
@@ -49,23 +47,17 @@ module Switchman
49
47
  begin
50
48
  @@shard1 = @@shard1.create_new_shard
51
49
  @@shard2 = @@shard2.create_new_shard
52
- if @@shard1.database_server == Shard.default.database_server
53
- @@shard3 = nil
54
- else
55
- @@shard3 = @@shard1.database_server.create_new_shard
56
- end
57
50
  rescue => e
58
- $stderr.puts "Sharding setup FAILED!:"
51
+ warn 'Sharding setup FAILED!:'
59
52
  while e
60
- $stderr.puts "\n#{e}\n"
61
- $stderr.puts e.backtrace
53
+ warn "\n#{e}\n"
54
+ warn e.backtrace
62
55
  e = e.respond_to?(:cause) ? e.cause : nil
63
56
  end
64
57
  @@sharding_failed = true
65
- (@@shard1.drop_database if @@shard1) rescue nil
66
- (@@shard2.drop_database if @@shard3) rescue nil
67
- (@@shard3.drop_database if @@shard3) rescue nil
68
- @@shard1 = @@shard2 = @@shard3 = nil
58
+ @@shard1&.drop_database rescue nil
59
+ @@shard2&.drop_database rescue nil
60
+ @@shard1 = @@shard2 = nil
69
61
  Shard.delete_all
70
62
  Shard.default(reload: true)
71
63
  next
@@ -74,24 +66,20 @@ module Switchman
74
66
  # we'll re-persist in the group's `before :all`; we don't want them to exist
75
67
  # in the db before then
76
68
  Shard.delete_all
77
- Switchman.cache.delete("default_shard")
69
+ Switchman.cache.delete('default_shard')
78
70
  Shard.default(reload: true)
79
- puts "Done!"
71
+ puts 'Done!'
80
72
 
81
73
  at_exit do
82
74
  # preserve rspec's exit status
83
- status= $!.is_a?(::SystemExit) ? $!.status : nil
84
- puts "Tearing down sharding for all specs"
75
+ status = $!.is_a?(::SystemExit) ? $!.status : nil
76
+ puts 'Tearing down sharding for all specs'
85
77
  @@shard1.database_server.destroy unless @@shard1.database_server == Shard.default.database_server
86
78
  unless @@keep_the_shards
87
79
  @@shard1.drop_database
88
80
  @@shard1.destroy
89
81
  @@shard2.drop_database
90
82
  @@shard2.destroy
91
- if @@shard3
92
- @@shard3.drop_database
93
- @@shard3.destroy
94
- end
95
83
  end
96
84
  @@shard2.database_server.destroy
97
85
  exit status if status
@@ -100,10 +88,11 @@ module Switchman
100
88
 
101
89
  klass.before(:all) do
102
90
  next if @@sharding_failed
91
+
103
92
  dup = @@default_shard.dup
104
93
  dup.id = @@default_shard.id
105
94
  dup.save!
106
- Switchman.cache.delete("default_shard")
95
+ Switchman.cache.delete('default_shard')
107
96
  Shard.default(reload: true)
108
97
  dup = @@shard1.dup
109
98
  dup.id = @@shard1.id
@@ -111,17 +100,12 @@ module Switchman
111
100
  dup = @@shard2.dup
112
101
  dup.id = @@shard2.id
113
102
  dup.save!
114
- if @@shard3
115
- dup = @@shard3.dup
116
- dup.id = @@shard3.id
117
- dup.save!
118
- end
119
103
  @shard1, @shard2 = @@shard1, @@shard2
120
- @shard3 = @@shard3 ? @@shard3 : Shard.default
121
104
  end
122
105
 
123
106
  klass.before do
124
- raise "Sharding did not set up correctly" if @@sharding_failed
107
+ raise 'Sharding did not set up correctly' if @@sharding_failed
108
+
125
109
  Shard.clear_cache
126
110
  if use_transactional_tests
127
111
  Shard.default(reload: true)
@@ -139,6 +123,7 @@ module Switchman
139
123
 
140
124
  klass.after do
141
125
  next if @@sharding_failed
126
+
142
127
  if use_transactional_tests
143
128
  shards = [@shard2]
144
129
  shards << @shard1 unless @shard1.database_server == Shard.default.database_server
@@ -148,11 +133,18 @@ module Switchman
148
133
  end
149
134
  end
150
135
  end
136
+ # clean up after specs
137
+ DatabaseServer.all.each do |ds|
138
+ if ds.fake? && ds != @shard2.database_server
139
+ ds.shards.delete_all unless use_transactional_tests
140
+ ds.destroy
141
+ end
142
+ end
151
143
  end
152
144
 
153
145
  klass.after(:all) do
154
146
  Shard.connection.update("TRUNCATE #{Shard.quoted_table_name} CASCADE")
155
- Switchman.cache.delete("default_shard")
147
+ Switchman.cache.delete('default_shard')
156
148
  Shard.default(reload: true)
157
149
  end
158
150
  end