switchman 2.0.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +10 -2
  3. data/app/models/switchman/shard.rb +234 -270
  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 +1 -1
  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 -3
  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 -85
  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 +73 -66
  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 -15
  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 +42 -53
  27. data/lib/switchman/active_record/predicate_builder.rb +1 -1
  28. data/lib/switchman/active_record/query_cache.rb +18 -19
  29. data/lib/switchman/active_record/query_methods.rb +172 -181
  30. data/lib/switchman/active_record/reflection.rb +6 -10
  31. data/lib/switchman/active_record/relation.rb +27 -21
  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 -57
  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 -1
  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 +6 -10
  50. data/lib/switchman/version.rb +1 -1
  51. data/lib/tasks/switchman.rake +54 -69
  52. metadata +100 -44
  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 -169
@@ -4,17 +4,44 @@ require 'switchman/database_server'
4
4
 
5
5
  module Switchman
6
6
  class DefaultShard
7
- def id; 'default'; end
7
+ def id
8
+ 'default'
9
+ end
8
10
  alias cache_key id
9
- def activate(*categories); yield; end
10
- def activate!(*categories); end
11
- def default?; true; end
12
- def primary?; true; end
13
- def relative_id_for(local_id, target = nil); local_id; end
14
- def global_id_for(local_id); local_id; end
15
- def database_server_id; nil; end
16
- def database_server; DatabaseServer.find(nil); end
17
- def new_record?; false; end
11
+ def activate(*_classes)
12
+ yield
13
+ end
14
+
15
+ def activate!(*classes); end
16
+
17
+ def default?
18
+ true
19
+ end
20
+
21
+ def primary?
22
+ true
23
+ end
24
+
25
+ def relative_id_for(local_id, _target = nil)
26
+ local_id
27
+ end
28
+
29
+ def global_id_for(local_id)
30
+ local_id
31
+ end
32
+
33
+ def database_server_id
34
+ nil
35
+ end
36
+
37
+ def database_server
38
+ DatabaseServer.find(nil)
39
+ end
40
+
41
+ def new_record?
42
+ false
43
+ end
44
+
18
45
  def name
19
46
  unless instance_variable_defined?(:@name)
20
47
  @name = nil # prevent taking this branch on recursion
@@ -22,18 +49,27 @@ module Switchman
22
49
  end
23
50
  @name
24
51
  end
25
- def description; ::Rails.env; end
52
+
53
+ def description
54
+ ::Rails.env
55
+ end
56
+
26
57
  # The default's shard is always the default shard
27
- def shard; self; end
28
- def _dump(depth)
58
+ def shard
59
+ self
60
+ end
61
+
62
+ def _dump(_depth)
29
63
  ''
30
64
  end
31
- def self._load(str)
65
+
66
+ def self._load(_str)
32
67
  Shard.default
33
68
  end
34
69
 
35
- def ==(rhs)
36
- return true if rhs.is_a?(DefaultShard) || (rhs.is_a?(Shard) && rhs[:default])
70
+ def ==(other)
71
+ return true if other.is_a?(DefaultShard) || (other.is_a?(Shard) && other[:default])
72
+
37
73
  super
38
74
  end
39
75
 
@@ -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,8 +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)
153
+
154
+ ::ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(ActiveRecord::Tasks::DatabaseTasks)
155
+
145
156
  ::ActiveRecord::TypeCaster::Map.include(ActiveRecord::TypeCaster::Map)
146
157
  ::ActiveRecord::TypeCaster::Connection.include(ActiveRecord::TypeCaster::Connection)
147
158
 
@@ -153,12 +164,10 @@ module Switchman
153
164
  end
154
165
 
155
166
  def self.foreign_key_check(name, type, limit: nil)
156
- if name.to_s =~ /_id\z/ && type.to_s == 'integer' && limit.to_i < 8
157
- 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`"
158
- 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
159
168
  end
160
169
 
161
- initializer 'switchman.extend_connection_adapters', :after => "active_record.initialize_database" do
170
+ initializer 'switchman.extend_connection_adapters', after: 'active_record.initialize_database' do
162
171
  ::ActiveSupport.on_load(:active_record) do
163
172
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.descendants.each do |klass|
164
173
  klass.prepend(ActiveRecord::AbstractAdapter::ForeignKeyCheck)
@@ -168,15 +177,11 @@ module Switchman
168
177
  ::ActiveRecord::ConnectionAdapters::TableDefinition.prepend(ActiveRecord::TableDefinition)
169
178
 
170
179
  if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
171
- require "switchman/active_record/postgresql_adapter"
180
+ require 'switchman/active_record/postgresql_adapter'
172
181
  ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
173
182
  end
174
183
 
175
- # If Switchman::Shard wasn't loaded as of when ActiveRecord::Base initialized
176
- # establish a connection here instead
177
- if !Shard.instance_variable_get(:@default)
178
- ::ActiveRecord::Base.establish_connection
179
- end
184
+ Shard.send(:initialize_sharding)
180
185
  end
181
186
  end
182
187
 
@@ -187,21 +192,20 @@ module Switchman
187
192
  end
188
193
  end
189
194
 
190
- initializer 'switchman.extend_guard_rail', :before => "switchman.extend_ar" do
195
+ initializer 'switchman.extend_guard_rail', before: 'switchman.extend_ar' do
191
196
  ::ActiveSupport.on_load(:active_record) do
192
- require "switchman/guard_rail"
197
+ require 'switchman/guard_rail'
193
198
 
194
199
  ::GuardRail.singleton_class.prepend(GuardRail::ClassMethods)
195
200
  end
196
201
  end
197
202
 
198
- initializer 'switchman.extend_controller', :after => "guard_rail.extend_ar" do
203
+ initializer 'switchman.extend_controller', after: 'guard_rail.extend_ar' do
199
204
  ::ActiveSupport.on_load(:action_controller) do
200
- require "switchman/action_controller/caching"
205
+ require 'switchman/action_controller/caching'
201
206
 
202
207
  ::ActionController::Base.include(ActionController::Caching)
203
208
  end
204
209
  end
205
-
206
210
  end
207
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