switchman 3.0.14 → 3.5.20
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.
- checksums.yaml +4 -4
- data/Rakefile +16 -15
- data/db/migrate/20180828183945_add_default_shard_index.rb +1 -1
- data/db/migrate/20190114212900_add_unique_name_indexes.rb +10 -4
- data/lib/switchman/action_controller/caching.rb +2 -2
- data/lib/switchman/active_record/abstract_adapter.rb +6 -6
- data/lib/switchman/active_record/associations.rb +365 -0
- data/lib/switchman/active_record/attribute_methods.rb +188 -99
- data/lib/switchman/active_record/base.rb +185 -40
- data/lib/switchman/active_record/calculations.rb +64 -40
- data/lib/switchman/active_record/connection_handler.rb +18 -0
- data/lib/switchman/active_record/connection_pool.rb +24 -5
- data/lib/switchman/active_record/database_configurations.rb +37 -13
- data/lib/switchman/active_record/finder_methods.rb +46 -16
- data/lib/switchman/active_record/log_subscriber.rb +11 -5
- data/lib/switchman/active_record/migration.rb +52 -8
- data/lib/switchman/active_record/model_schema.rb +1 -1
- data/lib/switchman/active_record/persistence.rb +31 -3
- data/lib/switchman/active_record/postgresql_adapter.rb +11 -10
- data/lib/switchman/active_record/predicate_builder.rb +2 -2
- data/lib/switchman/active_record/query_cache.rb +49 -20
- data/lib/switchman/active_record/query_methods.rb +187 -136
- data/lib/switchman/active_record/reflection.rb +1 -1
- data/lib/switchman/active_record/relation.rb +33 -26
- data/lib/switchman/active_record/spawn_methods.rb +2 -2
- data/lib/switchman/active_record/statement_cache.rb +11 -7
- data/lib/switchman/active_record/table_definition.rb +1 -1
- data/lib/switchman/active_record/tasks/database_tasks.rb +6 -1
- data/lib/switchman/active_record/test_fixtures.rb +26 -16
- data/lib/switchman/active_support/cache.rb +20 -1
- data/lib/switchman/arel.rb +34 -18
- data/lib/switchman/call_super.rb +8 -2
- data/lib/switchman/database_server.rb +91 -45
- data/lib/switchman/default_shard.rb +14 -5
- data/lib/switchman/engine.rb +79 -126
- data/lib/switchman/environment.rb +2 -2
- data/lib/switchman/errors.rb +17 -2
- data/lib/switchman/guard_rail/relation.rb +8 -10
- data/lib/switchman/guard_rail.rb +5 -0
- data/lib/switchman/parallel.rb +68 -0
- data/lib/switchman/r_spec_helper.rb +14 -11
- data/lib/switchman/rails.rb +2 -5
- data/{app/models → lib}/switchman/shard.rb +186 -189
- data/lib/switchman/sharded_instrumenter.rb +5 -1
- data/lib/switchman/shared_schema_cache.rb +11 -0
- data/lib/switchman/standard_error.rb +6 -5
- data/lib/switchman/test_helper.rb +2 -2
- data/{app/models → lib}/switchman/unsharded_record.rb +1 -1
- data/lib/switchman/version.rb +1 -1
- data/lib/switchman.rb +44 -12
- data/lib/tasks/switchman.rake +74 -53
- metadata +42 -53
- data/lib/switchman/active_record/association.rb +0 -206
- data/lib/switchman/open4.rb +0 -80
|
@@ -7,9 +7,14 @@ module Switchman
|
|
|
7
7
|
def drop(*)
|
|
8
8
|
super
|
|
9
9
|
# no really, it's gone
|
|
10
|
-
Switchman.cache.delete(
|
|
10
|
+
Switchman.cache.delete("default_shard")
|
|
11
11
|
Shard.default(reload: true)
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
def raise_for_multi_db(*)
|
|
15
|
+
# ignore; Switchman doesn't use namespaced tasks for multiple shards; it uses
|
|
16
|
+
# environment variables to filter which shards you want to target
|
|
17
|
+
end
|
|
13
18
|
end
|
|
14
19
|
end
|
|
15
20
|
end
|
|
@@ -12,31 +12,41 @@ module Switchman
|
|
|
12
12
|
# Replace the one that activerecord natively uses with a switchman-optimized one
|
|
13
13
|
::ActiveSupport::Notifications.unsubscribe(@connection_subscriber)
|
|
14
14
|
# Code adapted from the code in rails proper
|
|
15
|
-
@connection_subscriber =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
@connection_subscriber =
|
|
16
|
+
::ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
|
|
17
|
+
spec_name = if ::Rails.version < "7.1"
|
|
18
|
+
payload[:spec_name] if payload.key?(:spec_name)
|
|
19
|
+
elsif payload.key?(:connection_name)
|
|
20
|
+
payload[:connection_name]
|
|
21
|
+
end
|
|
22
|
+
shard = payload[:shard] if payload.key?(:shard)
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
if spec_name && !FORBIDDEN_DB_ENVS.include?(shard)
|
|
25
|
+
begin
|
|
26
|
+
connection = ::ActiveRecord::Base.connection_handler.retrieve_connection(spec_name, shard: shard)
|
|
27
|
+
connection.connect! if ::Rails.version >= "7.1" # eagerly validate the connection
|
|
28
|
+
rescue ::ActiveRecord::ConnectionNotEstablished, ::ActiveRecord::NoDatabaseError
|
|
29
|
+
connection = nil
|
|
30
|
+
end
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
if connection
|
|
33
|
+
setup_shared_connection_pool
|
|
34
|
+
unless @fixture_connections.include?(connection)
|
|
35
|
+
connection.begin_transaction joinable: false, _lazy: false
|
|
36
|
+
connection.pool.lock_thread = true if lock_threads
|
|
37
|
+
@fixture_connections << connection
|
|
38
|
+
end
|
|
39
|
+
end
|
|
31
40
|
end
|
|
32
41
|
end
|
|
33
|
-
end
|
|
34
42
|
end
|
|
35
43
|
|
|
36
44
|
def enlist_fixture_connections
|
|
37
45
|
setup_shared_connection_pool
|
|
38
46
|
|
|
39
|
-
::ActiveRecord::Base.connection_handler.connection_pool_list.reject
|
|
47
|
+
::ActiveRecord::Base.connection_handler.connection_pool_list(:primary).reject do |cp|
|
|
48
|
+
FORBIDDEN_DB_ENVS.include?(cp.db_config.env_name.to_sym)
|
|
49
|
+
end.map(&:connection)
|
|
40
50
|
end
|
|
41
51
|
end
|
|
42
52
|
end
|
|
@@ -4,11 +4,30 @@ module Switchman
|
|
|
4
4
|
module ActiveSupport
|
|
5
5
|
module Cache
|
|
6
6
|
module ClassMethods
|
|
7
|
+
def lookup_stores(cache_store_config)
|
|
8
|
+
result = {}
|
|
9
|
+
cache_store_config.each do |key, value|
|
|
10
|
+
next if value.is_a?(String)
|
|
11
|
+
|
|
12
|
+
result[key] = ::ActiveSupport::Cache.lookup_store(value)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
cache_store_config.each do |key, value| # rubocop:disable Style/CombinableLoops
|
|
16
|
+
next unless value.is_a?(String)
|
|
17
|
+
|
|
18
|
+
result[key] = result[value]
|
|
19
|
+
end
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
|
|
7
23
|
def lookup_store(*store_options)
|
|
8
24
|
store = super
|
|
9
25
|
# can't use defined?, because it's a _ruby_ autoloaded constant,
|
|
10
26
|
# so just checking that will cause it to get required
|
|
11
|
-
|
|
27
|
+
if store.instance_of?(ActiveSupport::Cache::RedisCacheStore) &&
|
|
28
|
+
!::ActiveSupport::Cache::RedisCacheStore <= RedisCacheStore
|
|
29
|
+
::ActiveSupport::Cache::RedisCacheStore.prepend(RedisCacheStore)
|
|
30
|
+
end
|
|
12
31
|
store.options[:namespace] ||= -> { Shard.current.default? ? nil : "shard_#{Shard.current.id}" }
|
|
13
32
|
store
|
|
14
33
|
end
|
data/lib/switchman/arel.rb
CHANGED
|
@@ -13,38 +13,54 @@ module Switchman
|
|
|
13
13
|
# rubocop:disable Naming/MethodName
|
|
14
14
|
# rubocop:disable Naming/MethodParameterName
|
|
15
15
|
|
|
16
|
+
def visit_Arel_Nodes_Cte(o, collector)
|
|
17
|
+
collector << quote_local_table_name(o.name)
|
|
18
|
+
collector << " AS "
|
|
19
|
+
|
|
20
|
+
case o.materialized
|
|
21
|
+
when true
|
|
22
|
+
collector << "MATERIALIZED "
|
|
23
|
+
when false
|
|
24
|
+
collector << "NOT MATERIALIZED "
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
visit o.relation, collector
|
|
28
|
+
end
|
|
29
|
+
|
|
16
30
|
def visit_Arel_Nodes_TableAlias(o, collector)
|
|
17
31
|
collector = visit o.relation, collector
|
|
18
|
-
collector <<
|
|
32
|
+
collector << " "
|
|
19
33
|
collector << quote_local_table_name(o.name)
|
|
20
34
|
end
|
|
21
35
|
|
|
22
36
|
def visit_Arel_Attributes_Attribute(o, collector)
|
|
23
37
|
join_name = o.relation.table_alias || o.relation.name
|
|
24
|
-
collector << quote_local_table_name(join_name) <<
|
|
38
|
+
collector << quote_local_table_name(join_name) << "." << quote_column_name(o.name)
|
|
25
39
|
end
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
if ::Rails.version < "7.1"
|
|
42
|
+
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
|
43
|
+
collector.preparable = false
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
collector << quote_local_table_name(o.table_name) << "." << quote_column_name(o.column_name)
|
|
31
46
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
47
|
+
collector << if o.type == :in
|
|
48
|
+
" IN ("
|
|
49
|
+
else
|
|
50
|
+
" NOT IN ("
|
|
51
|
+
end
|
|
37
52
|
|
|
38
|
-
|
|
53
|
+
values = o.casted_values
|
|
39
54
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
if values.empty?
|
|
56
|
+
collector << @connection.quote(nil)
|
|
57
|
+
else
|
|
58
|
+
collector.add_binds(values, o.proc_for_binds, &bind_block)
|
|
59
|
+
end
|
|
45
60
|
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
collector << ")"
|
|
62
|
+
collector
|
|
63
|
+
end
|
|
48
64
|
end
|
|
49
65
|
|
|
50
66
|
# rubocop:enable Naming/MethodName
|
data/lib/switchman/call_super.rb
CHANGED
|
@@ -12,8 +12,14 @@ module Switchman
|
|
|
12
12
|
method.super_method
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if RUBY_VERSION <= "2.8"
|
|
16
|
+
def call_super(method, above_module, *args, &block)
|
|
17
|
+
super_method_above(method, above_module).call(*args, &block)
|
|
18
|
+
end
|
|
19
|
+
else
|
|
20
|
+
def call_super(method, above_module, *args, **kwargs, &block)
|
|
21
|
+
super_method_above(method, above_module).call(*args, **kwargs, &block)
|
|
22
|
+
end
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "securerandom"
|
|
4
4
|
|
|
5
5
|
module Switchman
|
|
6
6
|
class DatabaseServer
|
|
@@ -8,24 +8,25 @@ module Switchman
|
|
|
8
8
|
|
|
9
9
|
class << self
|
|
10
10
|
attr_accessor :creating_new_shard
|
|
11
|
+
attr_reader :all_roles
|
|
12
|
+
|
|
13
|
+
include Enumerable
|
|
14
|
+
|
|
15
|
+
delegate :each, to: :all
|
|
11
16
|
|
|
12
17
|
def all
|
|
13
18
|
database_servers.values
|
|
14
19
|
end
|
|
15
20
|
|
|
16
|
-
def all_roles
|
|
17
|
-
@all_roles ||= all.map(&:roles).flatten.uniq
|
|
18
|
-
end
|
|
19
|
-
|
|
20
21
|
def find(id_or_all)
|
|
21
22
|
return all if id_or_all == :all
|
|
22
|
-
return id_or_all.
|
|
23
|
+
return id_or_all.filter_map { |id| database_servers[id || ::Rails.env] }.uniq if id_or_all.is_a?(Array)
|
|
23
24
|
|
|
24
25
|
database_servers[id_or_all || ::Rails.env]
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def create(settings = {})
|
|
28
|
-
raise
|
|
29
|
+
raise "database servers should be set up in database.yml" unless ::Rails.env.test?
|
|
29
30
|
|
|
30
31
|
id = settings[:id]
|
|
31
32
|
unless id
|
|
@@ -38,7 +39,7 @@ module Switchman
|
|
|
38
39
|
database_servers[server.id] = server
|
|
39
40
|
::ActiveRecord::Base.configurations.configurations <<
|
|
40
41
|
::ActiveRecord::DatabaseConfigurations::HashConfig.new(::Rails.env, "#{server.id}/primary", settings)
|
|
41
|
-
Shard.send(:
|
|
42
|
+
Shard.send(:configure_connects_to)
|
|
42
43
|
server
|
|
43
44
|
end
|
|
44
45
|
|
|
@@ -49,31 +50,48 @@ module Switchman
|
|
|
49
50
|
servers[rand(servers.length)]
|
|
50
51
|
end
|
|
51
52
|
|
|
53
|
+
def guard_servers
|
|
54
|
+
all.each { |db| db.guard! if db.config[:prefer_secondary] }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def regions
|
|
58
|
+
@regions ||= all.filter_map(&:region).uniq.sort
|
|
59
|
+
end
|
|
60
|
+
|
|
52
61
|
private
|
|
53
62
|
|
|
54
63
|
def reference_role(role)
|
|
55
64
|
return if all_roles.include?(role)
|
|
56
65
|
|
|
57
66
|
@all_roles << role
|
|
58
|
-
Shard.send(:
|
|
67
|
+
Shard.send(:configure_connects_to)
|
|
59
68
|
end
|
|
60
69
|
|
|
61
70
|
def database_servers
|
|
62
71
|
if !@database_servers || @database_servers.empty?
|
|
63
72
|
@database_servers = {}.with_indifferent_access
|
|
73
|
+
roles = []
|
|
64
74
|
::ActiveRecord::Base.configurations.configurations.each do |config|
|
|
65
|
-
if config.name.include?(
|
|
66
|
-
name, role = config.name.split(
|
|
75
|
+
if config.name.include?("/")
|
|
76
|
+
name, role = config.name.split("/")
|
|
67
77
|
else
|
|
68
78
|
name, role = config.env_name, config.name
|
|
69
79
|
end
|
|
80
|
+
role = role.to_sym
|
|
70
81
|
|
|
71
|
-
|
|
82
|
+
roles << role
|
|
83
|
+
if role == :primary
|
|
72
84
|
@database_servers[name] = DatabaseServer.new(config.env_name, config.configuration_hash)
|
|
73
85
|
else
|
|
74
86
|
@database_servers[name].roles << role
|
|
75
87
|
end
|
|
76
88
|
end
|
|
89
|
+
# Do this after so that all database servers for all roles are established and we won't prematurely
|
|
90
|
+
# configure a connection for the wrong role
|
|
91
|
+
@all_roles = roles.uniq
|
|
92
|
+
return @database_servers if @database_servers.empty?
|
|
93
|
+
|
|
94
|
+
Shard.send(:configure_connects_to)
|
|
77
95
|
end
|
|
78
96
|
@database_servers
|
|
79
97
|
end
|
|
@@ -102,8 +120,9 @@ module Switchman
|
|
|
102
120
|
self.class.send(:database_servers).delete(id) if id
|
|
103
121
|
Shard.sharded_models.each do |klass|
|
|
104
122
|
self.class.all_roles.each do |role|
|
|
105
|
-
klass.connection_handler.remove_connection_pool(klass.connection_specification_name,
|
|
106
|
-
|
|
123
|
+
klass.connection_handler.remove_connection_pool(klass.connection_specification_name,
|
|
124
|
+
role: role,
|
|
125
|
+
shard: id.to_sym)
|
|
107
126
|
end
|
|
108
127
|
end
|
|
109
128
|
end
|
|
@@ -129,32 +148,57 @@ module Switchman
|
|
|
129
148
|
end
|
|
130
149
|
end
|
|
131
150
|
|
|
132
|
-
def
|
|
133
|
-
|
|
151
|
+
def region
|
|
152
|
+
config[:region]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# @param region [String, Array<String>] the region(s) to check against
|
|
156
|
+
# @return true if the database server doesn't have a region, or it
|
|
157
|
+
# matches the specified region
|
|
158
|
+
def in_region?(region)
|
|
159
|
+
!self.region || (region.is_a?(Array) ? region.include?(self.region) : self.region == region)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# @return true if the database server doesn't have a region, Switchman is
|
|
163
|
+
# not configured with a region, or the database server's region matches
|
|
164
|
+
# Switchman's current region
|
|
165
|
+
def in_current_region?
|
|
166
|
+
unless instance_variable_defined?(:@in_current_region)
|
|
167
|
+
@in_current_region = !region ||
|
|
168
|
+
!Switchman.region ||
|
|
169
|
+
region == Switchman.region
|
|
170
|
+
end
|
|
171
|
+
@in_current_region
|
|
134
172
|
end
|
|
135
173
|
|
|
136
174
|
# locks this db to a specific environment, except for
|
|
137
175
|
# when doing writes (then it falls back to the current
|
|
138
176
|
# value of GuardRail.environment)
|
|
139
177
|
def guard!(environment = :secondary)
|
|
140
|
-
|
|
178
|
+
DatabaseServer.send(:reference_role, environment)
|
|
179
|
+
::ActiveRecord::Base.connected_to_stack << { shard_roles: { id.to_sym => environment },
|
|
180
|
+
klasses: [::ActiveRecord::Base] }
|
|
141
181
|
end
|
|
142
182
|
|
|
143
183
|
def unguard!
|
|
144
|
-
|
|
184
|
+
::ActiveRecord::Base.connected_to_stack << { shard_roles: { id.to_sym => :_switchman_inherit },
|
|
185
|
+
klasses: [::ActiveRecord::Base] }
|
|
145
186
|
end
|
|
146
187
|
|
|
147
188
|
def unguard
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
189
|
+
return yield unless ::ActiveRecord::Base.role_overriden?(id.to_sym)
|
|
190
|
+
|
|
191
|
+
begin
|
|
192
|
+
unguard!
|
|
193
|
+
yield
|
|
194
|
+
ensure
|
|
195
|
+
::ActiveRecord::Base.connected_to_stack.pop
|
|
196
|
+
end
|
|
153
197
|
end
|
|
154
198
|
|
|
155
199
|
def shards
|
|
156
200
|
if id == ::Rails.env
|
|
157
|
-
Shard.where(
|
|
201
|
+
Shard.where("database_server_id IS NULL OR database_server_id=?", id)
|
|
158
202
|
else
|
|
159
203
|
Shard.where(database_server_id: id)
|
|
160
204
|
end
|
|
@@ -179,7 +223,7 @@ module Switchman
|
|
|
179
223
|
end
|
|
180
224
|
|
|
181
225
|
id ||= begin
|
|
182
|
-
id_seq = Shard.connection.quote(Shard.connection.quote_table_name(
|
|
226
|
+
id_seq = Shard.connection.quote(Shard.connection.quote_table_name("switchman_shards_id_seq"))
|
|
183
227
|
next_id = Shard.connection.select_value("SELECT nextval(#{id_seq})")
|
|
184
228
|
next_id.to_i
|
|
185
229
|
end
|
|
@@ -196,29 +240,32 @@ module Switchman
|
|
|
196
240
|
name: name,
|
|
197
241
|
database_server_id: self.id)
|
|
198
242
|
if create_statement
|
|
199
|
-
if ::ActiveRecord::Base.connection.select_value(
|
|
243
|
+
if ::ActiveRecord::Base.connection.select_value(
|
|
244
|
+
"SELECT 1 FROM pg_namespace WHERE nspname=#{::ActiveRecord::Base.connection.quote(name)}"
|
|
245
|
+
)
|
|
200
246
|
schema_already_existed = true
|
|
201
|
-
raise
|
|
247
|
+
raise "This schema already exists; cannot overwrite"
|
|
202
248
|
end
|
|
203
249
|
Array(create_statement.call).each do |stmt|
|
|
204
250
|
::ActiveRecord::Base.connection.execute(stmt)
|
|
205
251
|
end
|
|
206
252
|
end
|
|
207
|
-
if config[:adapter] ==
|
|
208
|
-
old_proc = ::ActiveRecord::Base.connection.raw_connection.set_notice_processor
|
|
209
|
-
end
|
|
253
|
+
if config[:adapter] == "postgresql"
|
|
254
|
+
old_proc = ::ActiveRecord::Base.connection.raw_connection.set_notice_processor {}
|
|
210
255
|
end
|
|
211
256
|
old_verbose = ::ActiveRecord::Migration.verbose
|
|
212
257
|
::ActiveRecord::Migration.verbose = false
|
|
213
258
|
|
|
214
259
|
unless schema == false
|
|
215
260
|
shard.activate do
|
|
216
|
-
reset_column_information
|
|
217
|
-
|
|
218
261
|
::ActiveRecord::Base.connection.transaction(requires_new: true) do
|
|
219
|
-
::
|
|
262
|
+
if ::Rails.version < "7.1"
|
|
263
|
+
::ActiveRecord::Base.connection.migration_context.migrate
|
|
264
|
+
else
|
|
265
|
+
::ActiveRecord::MigrationContext.new(::ActiveRecord::Migrator.migrations_paths).migrate
|
|
266
|
+
end
|
|
220
267
|
end
|
|
221
|
-
|
|
268
|
+
|
|
222
269
|
::ActiveRecord::Base.descendants.reject do |m|
|
|
223
270
|
m <= UnshardedRecord || !m.table_exists?
|
|
224
271
|
end.each(&:define_attribute_methods)
|
|
@@ -232,7 +279,6 @@ module Switchman
|
|
|
232
279
|
rescue
|
|
233
280
|
shard&.destroy
|
|
234
281
|
shard&.drop_database rescue nil unless schema_already_existed
|
|
235
|
-
reset_column_information unless schema == false rescue nil
|
|
236
282
|
raise
|
|
237
283
|
ensure
|
|
238
284
|
self.class.creating_new_shard = false
|
|
@@ -257,18 +303,18 @@ module Switchman
|
|
|
257
303
|
end
|
|
258
304
|
|
|
259
305
|
def primary_shard
|
|
260
|
-
unless
|
|
261
|
-
# if sharding isn't fully set up yet, we may not be able to query the shards table
|
|
262
|
-
@primary_shard = Shard.default if Shard.default.database_server == self
|
|
263
|
-
@primary_shard ||= shards.where(name: nil).first
|
|
264
|
-
end
|
|
265
|
-
@primary_shard
|
|
266
|
-
end
|
|
306
|
+
return nil unless primary_shard_id
|
|
267
307
|
|
|
268
|
-
|
|
308
|
+
Shard.lookup(primary_shard_id)
|
|
309
|
+
end
|
|
269
310
|
|
|
270
|
-
def
|
|
271
|
-
|
|
311
|
+
def primary_shard_id
|
|
312
|
+
unless instance_variable_defined?(:@primary_shard_id)
|
|
313
|
+
# if sharding isn't fully set up yet, we may not be able to query the shards table
|
|
314
|
+
@primary_shard_id = Shard.default.id if Shard.default.database_server == self
|
|
315
|
+
@primary_shard_id ||= shards.where(name: nil).first&.id
|
|
316
|
+
end
|
|
317
|
+
@primary_shard_id
|
|
272
318
|
end
|
|
273
319
|
end
|
|
274
320
|
end
|
|
@@ -1,13 +1,12 @@
|
|
|
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
|
-
|
|
6
|
+
"default"
|
|
9
7
|
end
|
|
10
|
-
|
|
8
|
+
alias_method :cache_key, :id
|
|
9
|
+
|
|
11
10
|
def activate(*_classes)
|
|
12
11
|
yield
|
|
13
12
|
end
|
|
@@ -59,8 +58,18 @@ module Switchman
|
|
|
59
58
|
self
|
|
60
59
|
end
|
|
61
60
|
|
|
61
|
+
def region; end
|
|
62
|
+
|
|
63
|
+
def in_region?(_region)
|
|
64
|
+
true
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def in_current_region?
|
|
68
|
+
true
|
|
69
|
+
end
|
|
70
|
+
|
|
62
71
|
def _dump(_depth)
|
|
63
|
-
|
|
72
|
+
""
|
|
64
73
|
end
|
|
65
74
|
|
|
66
75
|
def self._load(_str)
|