switchman 2.0.7 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +10 -2
- data/app/models/switchman/shard.rb +234 -270
- data/app/models/switchman/unsharded_record.rb +7 -0
- data/db/migrate/20130328212039_create_switchman_shards.rb +1 -1
- data/db/migrate/20130328224244_create_default_shard.rb +5 -5
- data/db/migrate/20161206323434_add_back_default_string_limits_switchman.rb +1 -0
- data/db/migrate/20180828183945_add_default_shard_index.rb +1 -1
- data/db/migrate/20180828192111_add_timestamps_to_shards.rb +7 -5
- data/db/migrate/20190114212900_add_unique_name_indexes.rb +5 -3
- data/lib/switchman.rb +3 -3
- data/lib/switchman/action_controller/caching.rb +2 -2
- data/lib/switchman/active_record/abstract_adapter.rb +1 -0
- data/lib/switchman/active_record/association.rb +78 -89
- data/lib/switchman/active_record/attribute_methods.rb +58 -52
- data/lib/switchman/active_record/base.rb +58 -59
- data/lib/switchman/active_record/calculations.rb +73 -66
- data/lib/switchman/active_record/connection_pool.rb +14 -41
- data/lib/switchman/active_record/database_configurations.rb +34 -0
- data/lib/switchman/active_record/database_configurations/database_config.rb +13 -0
- data/lib/switchman/active_record/finder_methods.rb +11 -16
- data/lib/switchman/active_record/log_subscriber.rb +4 -8
- data/lib/switchman/active_record/migration.rb +5 -14
- data/lib/switchman/active_record/model_schema.rb +1 -1
- data/lib/switchman/active_record/persistence.rb +4 -6
- data/lib/switchman/active_record/postgresql_adapter.rb +42 -53
- data/lib/switchman/active_record/predicate_builder.rb +1 -1
- data/lib/switchman/active_record/query_cache.rb +18 -19
- data/lib/switchman/active_record/query_methods.rb +172 -181
- data/lib/switchman/active_record/reflection.rb +6 -10
- data/lib/switchman/active_record/relation.rb +27 -21
- data/lib/switchman/active_record/spawn_methods.rb +27 -29
- data/lib/switchman/active_record/statement_cache.rb +18 -35
- data/lib/switchman/active_record/tasks/database_tasks.rb +16 -0
- data/lib/switchman/active_support/cache.rb +3 -5
- data/lib/switchman/arel.rb +13 -8
- data/lib/switchman/database_server.rb +121 -142
- data/lib/switchman/default_shard.rb +52 -16
- data/lib/switchman/engine.rb +61 -57
- data/lib/switchman/environment.rb +4 -8
- data/lib/switchman/errors.rb +1 -0
- data/lib/switchman/guard_rail.rb +6 -19
- data/lib/switchman/guard_rail/relation.rb +5 -7
- data/lib/switchman/r_spec_helper.rb +29 -37
- data/lib/switchman/rails.rb +14 -12
- data/lib/switchman/schema_cache.rb +1 -1
- data/lib/switchman/sharded_instrumenter.rb +1 -1
- data/lib/switchman/standard_error.rb +15 -3
- data/lib/switchman/test_helper.rb +6 -10
- data/lib/switchman/version.rb +1 -1
- data/lib/tasks/switchman.rake +54 -69
- metadata +90 -48
- data/lib/switchman/active_record/batches.rb +0 -11
- data/lib/switchman/active_record/connection_handler.rb +0 -172
- data/lib/switchman/active_record/where_clause_factory.rb +0 -36
- 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
|
7
|
+
def id
|
8
|
+
'default'
|
9
|
+
end
|
8
10
|
alias cache_key id
|
9
|
-
def activate(*
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def
|
14
|
-
|
15
|
-
def
|
16
|
-
|
17
|
-
|
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
|
-
|
52
|
+
|
53
|
+
def description
|
54
|
+
::Rails.env
|
55
|
+
end
|
56
|
+
|
26
57
|
# The default's shard is always the default shard
|
27
|
-
def shard
|
28
|
-
|
58
|
+
def shard
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
def _dump(_depth)
|
29
63
|
''
|
30
64
|
end
|
31
|
-
|
65
|
+
|
66
|
+
def self._load(_str)
|
32
67
|
Shard.default
|
33
68
|
end
|
34
69
|
|
35
|
-
def ==(
|
36
|
-
return true if
|
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
|
|
data/lib/switchman/engine.rb
CHANGED
@@ -4,24 +4,30 @@ module Switchman
|
|
4
4
|
class Engine < ::Rails::Engine
|
5
5
|
isolate_namespace Switchman
|
6
6
|
|
7
|
-
|
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', :
|
24
|
-
require
|
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].
|
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(
|
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', :
|
69
|
+
initializer 'switchman.extend_ar', before: 'active_record.initialize_database' do
|
66
70
|
::ActiveSupport.on_load(:active_record) do
|
67
|
-
require
|
68
|
-
require
|
69
|
-
require
|
70
|
-
require
|
71
|
-
require
|
72
|
-
require
|
73
|
-
require
|
74
|
-
require
|
75
|
-
require
|
76
|
-
require
|
77
|
-
require
|
78
|
-
require
|
79
|
-
require
|
80
|
-
require
|
81
|
-
require
|
82
|
-
require
|
83
|
-
require
|
84
|
-
require
|
85
|
-
require
|
86
|
-
require
|
87
|
-
require
|
88
|
-
require
|
89
|
-
require
|
90
|
-
require
|
91
|
-
require
|
92
|
-
require
|
93
|
-
|
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)
|
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', :
|
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
|
180
|
+
require 'switchman/active_record/postgresql_adapter'
|
172
181
|
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
|
173
182
|
end
|
174
183
|
|
175
|
-
|
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', :
|
195
|
+
initializer 'switchman.extend_guard_rail', before: 'switchman.extend_ar' do
|
191
196
|
::ActiveSupport.on_load(:active_record) do
|
192
|
-
require
|
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', :
|
203
|
+
initializer 'switchman.extend_controller', after: 'guard_rail.extend_ar' do
|
199
204
|
::ActiveSupport.on_load(:action_controller) do
|
200
|
-
require
|
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
|
-
|
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
|
-
|
13
|
+
0
|
17
14
|
end
|
18
|
-
|
19
15
|
end
|
20
16
|
end
|
data/lib/switchman/errors.rb
CHANGED
data/lib/switchman/guard_rail.rb
CHANGED
@@ -3,27 +3,14 @@
|
|
3
3
|
module Switchman
|
4
4
|
module GuardRail
|
5
5
|
module ClassMethods
|
6
|
-
def
|
7
|
-
|
6
|
+
def activate(role)
|
7
|
+
DatabaseServer.send(:reference_role, role)
|
8
|
+
super
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
8
|
-
db = Shard.current(
|
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
|
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(
|
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
|
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
|
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?{ |
|
35
|
+
next unless groups.any? { |descendant_group| RSpecHelper.included_in?(descendant_group) }
|
38
36
|
|
39
|
-
puts
|
37
|
+
puts 'Setting up sharding for all specs...'
|
40
38
|
Shard.delete_all
|
41
|
-
Switchman.cache.delete(
|
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
|
-
|
51
|
+
warn 'Sharding setup FAILED!:'
|
59
52
|
while e
|
60
|
-
|
61
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
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(
|
69
|
+
Switchman.cache.delete('default_shard')
|
78
70
|
Shard.default(reload: true)
|
79
|
-
puts
|
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
|
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(
|
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
|
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(
|
147
|
+
Switchman.cache.delete('default_shard')
|
156
148
|
Shard.default(reload: true)
|
157
149
|
end
|
158
150
|
end
|