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.
- checksums.yaml +4 -4
- data/Rakefile +10 -2
- data/app/models/switchman/shard.rb +234 -271
- 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 +2 -2
- 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 -5
- 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 +74 -67
- 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 +6 -47
- 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 +124 -168
- data/lib/switchman/active_record/predicate_builder.rb +2 -2
- data/lib/switchman/active_record/query_cache.rb +18 -19
- data/lib/switchman/active_record/query_methods.rb +172 -197
- data/lib/switchman/active_record/reflection.rb +6 -10
- data/lib/switchman/active_record/relation.rb +30 -78
- 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 -58
- 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 -9
- data/lib/switchman/sharded_instrumenter.rb +1 -1
- data/lib/switchman/standard_error.rb +15 -3
- data/lib/switchman/test_helper.rb +7 -11
- data/lib/switchman/version.rb +1 -1
- data/lib/tasks/switchman.rake +54 -69
- metadata +87 -45
- 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 -173
@@ -5,7 +5,7 @@ module Switchman
|
|
5
5
|
module Reflection
|
6
6
|
module AbstractReflection
|
7
7
|
def shard(owner)
|
8
|
-
if polymorphic? || klass.
|
8
|
+
if polymorphic? || klass.connection_classes == owner.class.connection_classes
|
9
9
|
# polymorphic associations assume the same shard as the owning item
|
10
10
|
owner.shard
|
11
11
|
else
|
@@ -28,21 +28,17 @@ module Switchman
|
|
28
28
|
# this technically belongs on AssociationReflection, but we put it on
|
29
29
|
# ThroughReflection as well, instead of delegating to its internal
|
30
30
|
# HasManyAssociation, losing its proper `klass`
|
31
|
-
def association_scope_cache(
|
32
|
-
key =
|
33
|
-
if polymorphic?
|
34
|
-
key = [key, owner._read_attribute(@foreign_type)]
|
35
|
-
end
|
31
|
+
def association_scope_cache(klass, owner, &block)
|
32
|
+
key = self
|
33
|
+
key = [key, owner._read_attribute(@foreign_type)] if polymorphic?
|
36
34
|
key = [key, shard(owner).id].flatten
|
37
|
-
|
38
|
-
@association_scope_cache[key] ||= (::Rails.version >= "5.2" ? ::ActiveRecord::StatementCache.create(conn, &block) : block.call)
|
39
|
-
}
|
35
|
+
klass.cached_find_by_statement(key, &block)
|
40
36
|
end
|
41
37
|
end
|
42
38
|
|
43
39
|
module AssociationReflection
|
44
40
|
def join_id_for(owner)
|
45
|
-
owner.send(
|
41
|
+
owner.send(join_foreign_key) # use sharded id values in association binds
|
46
42
|
end
|
47
43
|
end
|
48
44
|
end
|
@@ -4,53 +4,54 @@ module Switchman
|
|
4
4
|
module ActiveRecord
|
5
5
|
module Relation
|
6
6
|
def self.prepended(klass)
|
7
|
-
klass::SINGLE_VALUE_METHODS.concat [
|
7
|
+
klass::SINGLE_VALUE_METHODS.concat %i[shard shard_source]
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize(*, **)
|
11
11
|
super
|
12
|
-
self.shard_value = Shard.current(klass ? klass.
|
12
|
+
self.shard_value = Shard.current(klass ? klass.connection_classes : :primary) unless shard_value
|
13
13
|
self.shard_source_value = :implicit unless shard_source_value
|
14
14
|
end
|
15
15
|
|
16
16
|
def clone
|
17
17
|
result = super
|
18
|
-
result.shard_value = Shard.current(klass ? klass.
|
18
|
+
result.shard_value = Shard.current(klass ? klass.connection_classes : :primary) unless shard_value
|
19
19
|
result
|
20
20
|
end
|
21
21
|
|
22
22
|
def merge(*)
|
23
23
|
relation = super
|
24
|
-
if relation.shard_value !=
|
25
|
-
relation.shard_value =
|
26
|
-
relation.shard_source_value =
|
24
|
+
if relation.shard_value != shard_value && relation.shard_source_value == :implicit
|
25
|
+
relation.shard_value = shard_value
|
26
|
+
relation.shard_source_value = shard_source_value
|
27
27
|
end
|
28
28
|
relation
|
29
29
|
end
|
30
30
|
|
31
31
|
def new(*, &block)
|
32
|
-
primary_shard.activate(klass.
|
32
|
+
primary_shard.activate(klass.connection_classes) { super }
|
33
33
|
end
|
34
34
|
|
35
35
|
def create(*, &block)
|
36
|
-
primary_shard.activate(klass.
|
36
|
+
primary_shard.activate(klass.connection_classes) { super }
|
37
37
|
end
|
38
38
|
|
39
39
|
def create!(*, &block)
|
40
|
-
primary_shard.activate(klass.
|
40
|
+
primary_shard.activate(klass.connection_classes) { super }
|
41
41
|
end
|
42
42
|
|
43
43
|
def to_sql
|
44
|
-
primary_shard.activate(klass.
|
44
|
+
primary_shard.activate(klass.connection_classes) { super }
|
45
45
|
end
|
46
46
|
|
47
47
|
def explain
|
48
|
-
|
48
|
+
activate { |relation| relation.call_super(:explain, Relation) }
|
49
49
|
end
|
50
50
|
|
51
51
|
def records
|
52
52
|
return @records if loaded?
|
53
|
-
|
53
|
+
|
54
|
+
results = activate { |relation| relation.call_super(:records, Relation) }
|
54
55
|
case shard_value
|
55
56
|
when Array, ::ActiveRecord::Relation, ::ActiveRecord::Base
|
56
57
|
@records = results
|
@@ -59,10 +60,10 @@ module Switchman
|
|
59
60
|
results
|
60
61
|
end
|
61
62
|
|
62
|
-
%I
|
63
|
+
%I[update_all delete_all].each do |method|
|
63
64
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
64
65
|
def #{method}(*args)
|
65
|
-
result = self.activate
|
66
|
+
result = self.activate { |relation| relation.call_super(#{method.inspect}, Relation, *args) }
|
66
67
|
result = result.sum if result.is_a?(Array)
|
67
68
|
result
|
68
69
|
end
|
@@ -74,15 +75,20 @@ module Switchman
|
|
74
75
|
loose_mode = options[:loose] && is_integer
|
75
76
|
# loose_mode: if we don't care about getting exactly batch_size ids in between
|
76
77
|
# don't get the max - just get the min and add batch_size so we get that many _at most_
|
77
|
-
values = loose_mode ?
|
78
|
+
values = loose_mode ? 'MIN(id)' : 'MIN(id), MAX(id)'
|
78
79
|
|
79
80
|
batch_size = options[:batch_size].try(:to_i) || 1000
|
80
81
|
quoted_primary_key = "#{klass.connection.quote_local_table_name(table_name)}.#{klass.connection.quote_column_name(primary_key)}"
|
81
|
-
as_id =
|
82
|
+
as_id = ' AS id' unless primary_key == 'id'
|
82
83
|
subquery_scope = except(:select).select("#{quoted_primary_key}#{as_id}").reorder(primary_key.to_sym).limit(loose_mode ? 1 : batch_size)
|
83
84
|
subquery_scope = subquery_scope.where("#{quoted_primary_key} <= ?", options[:end_at]) if options[:end_at]
|
84
85
|
|
85
|
-
first_subquery_scope =
|
86
|
+
first_subquery_scope = if options[:start_at]
|
87
|
+
subquery_scope.where("#{quoted_primary_key} >= ?",
|
88
|
+
options[:start_at])
|
89
|
+
else
|
90
|
+
subquery_scope
|
91
|
+
end
|
86
92
|
|
87
93
|
ids = connection.select_rows("SELECT #{values} FROM (#{first_subquery_scope.to_sql}) AS subquery").first
|
88
94
|
|
@@ -97,73 +103,19 @@ module Switchman
|
|
97
103
|
end
|
98
104
|
end
|
99
105
|
|
100
|
-
def activate(
|
106
|
+
def activate(&block)
|
101
107
|
shards = all_shards
|
102
|
-
if
|
103
|
-
if shards.first == DefaultShard || shards.first == Shard.current(klass.
|
108
|
+
if Array === shards && shards.length == 1
|
109
|
+
if shards.first == DefaultShard || shards.first == Shard.current(klass.connection_classes)
|
104
110
|
yield(self, shards.first)
|
105
111
|
else
|
106
|
-
shards.first.activate(klass.
|
112
|
+
shards.first.activate(klass.connection_classes) { yield(self, shards.first) }
|
107
113
|
end
|
108
114
|
else
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# don't even query other shards if we're already past the limit
|
113
|
-
next if limit_value && result_count >= limit_value && order_values.empty?
|
114
|
-
|
115
|
-
relation = shard(Shard.current(klass.shard_category), :to_a)
|
116
|
-
# do a minimal query if possible
|
117
|
-
relation = relation.limit(limit_value - result_count) if limit_value && !result_count.zero? && order_values.empty?
|
118
|
-
|
119
|
-
shard_results = relation.activate(&block)
|
120
|
-
|
121
|
-
if shard_results.present? && !unordered
|
122
|
-
can_order ||= can_order_cross_shard_results? unless order_values.empty?
|
123
|
-
raise OrderOnMultiShardQuery if !can_order && !order_values.empty? && result_count.positive?
|
124
|
-
|
125
|
-
result_count += shard_results.is_a?(Array) ? shard_results.length : 1
|
126
|
-
end
|
127
|
-
shard_results
|
128
|
-
end
|
129
|
-
|
130
|
-
result = reorder_cross_shard_results(result) if can_order
|
131
|
-
result.slice!(limit_value..-1) if limit_value
|
132
|
-
result
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def can_order_cross_shard_results?
|
137
|
-
# we only presume to be able to post-sort the most basic of orderings
|
138
|
-
order_values.all? { |ov| ov.is_a?(::Arel::Nodes::Ordering) && ov.expr.is_a?(::Arel::Attributes::Attribute) }
|
139
|
-
end
|
140
|
-
|
141
|
-
def reorder_cross_shard_results(results)
|
142
|
-
results.sort! do |l, r|
|
143
|
-
result = 0
|
144
|
-
order_values.each do |ov|
|
145
|
-
if !l.is_a?(::ActiveRecord::Base)
|
146
|
-
a, b = l, r
|
147
|
-
elsif l.respond_to?(ov.expr.name)
|
148
|
-
a = l.send(ov.expr.name)
|
149
|
-
b = r.send(ov.expr.name)
|
150
|
-
else
|
151
|
-
a = l.attributes[ov.expr.name]
|
152
|
-
b = r.attributes[ov.expr.name]
|
153
|
-
end
|
154
|
-
next if a == b
|
155
|
-
|
156
|
-
if a.nil? || b.nil?
|
157
|
-
result = 1 if a.nil?
|
158
|
-
result *= -1 if ov.is_a?(::Arel::Nodes::Descending)
|
159
|
-
else
|
160
|
-
result = a <=> b
|
161
|
-
end
|
162
|
-
|
163
|
-
result *= -1 if ov.is_a?(::Arel::Nodes::Descending)
|
164
|
-
break unless result.zero?
|
115
|
+
# TODO: implement local limit to avoid querying extra shards
|
116
|
+
Shard.with_each_shard(shards, [klass.connection_classes]) do
|
117
|
+
shard(Shard.current(klass.connection_classes), :to_a).activate(&block)
|
165
118
|
end
|
166
|
-
result
|
167
119
|
end
|
168
120
|
end
|
169
121
|
end
|
@@ -3,27 +3,27 @@
|
|
3
3
|
module Switchman
|
4
4
|
module ActiveRecord
|
5
5
|
module SpawnMethods
|
6
|
-
def shard_values_for_merge(
|
7
|
-
if shard_value !=
|
8
|
-
if
|
6
|
+
def shard_values_for_merge(rhs)
|
7
|
+
if shard_value != rhs.shard_value
|
8
|
+
if rhs.shard_source_value == :implicit
|
9
9
|
final_shard_value = shard_value
|
10
10
|
final_primary_shard = primary_shard
|
11
11
|
final_shard_source_value = shard_source_value
|
12
12
|
elsif shard_source_value == :implicit
|
13
|
-
final_shard_value =
|
14
|
-
final_primary_shard =
|
15
|
-
final_shard_source_value =
|
13
|
+
final_shard_value = rhs.shard_value
|
14
|
+
final_primary_shard = rhs.primary_shard
|
15
|
+
final_shard_source_value = rhs.shard_source_value
|
16
16
|
else
|
17
|
-
final_shard_source_value = [
|
18
|
-
shard_source_value == source_value ||
|
17
|
+
final_shard_source_value = %i[explicit association].detect do |source_value|
|
18
|
+
shard_source_value == source_value || rhs.shard_source_value == source_value
|
19
19
|
end
|
20
|
-
raise
|
20
|
+
raise 'unknown shard_source_value' unless final_shard_source_value
|
21
21
|
|
22
22
|
# have to merge shard_value
|
23
23
|
lhs_shard_value = all_shards
|
24
|
-
rhs_shard_value =
|
25
|
-
if
|
26
|
-
|
24
|
+
rhs_shard_value = rhs.all_shards
|
25
|
+
if ::ActiveRecord::Relation === lhs_shard_value &&
|
26
|
+
::ActiveRecord::Relation === rhs_shard_value
|
27
27
|
final_shard_value = lhs_shard_value.merge(rhs_shard_value)
|
28
28
|
final_primary_shard = Shard.default
|
29
29
|
else
|
@@ -32,27 +32,25 @@ module Switchman
|
|
32
32
|
final_shard_value = final_shard_value.first if final_shard_value.length == 1
|
33
33
|
end
|
34
34
|
end
|
35
|
-
elsif shard_source_value !=
|
36
|
-
final_shard_source_value = [
|
37
|
-
shard_source_value == source_value ||
|
35
|
+
elsif shard_source_value != rhs.shard_source_value
|
36
|
+
final_shard_source_value = %i[explicit association implicit].detect do |source_value|
|
37
|
+
shard_source_value == source_value || rhs.shard_source_value == source_value
|
38
38
|
end
|
39
|
-
raise
|
40
|
-
else
|
41
|
-
# nothing fancy
|
39
|
+
raise 'unknown shard_source_value' unless final_shard_source_value
|
42
40
|
end
|
43
41
|
|
44
42
|
[final_shard_value, final_primary_shard, final_shard_source_value]
|
45
43
|
end
|
46
44
|
|
47
|
-
def merge!(
|
48
|
-
return super unless ::ActiveRecord::Relation ===
|
45
|
+
def merge!(rhs)
|
46
|
+
return super unless ::ActiveRecord::Relation === rhs
|
49
47
|
|
50
48
|
# have to figure out shard stuff *before* conditions are merged
|
51
|
-
final_shard_value, final_primary_shard, final_shard_source_value = shard_values_for_merge(
|
49
|
+
final_shard_value, final_primary_shard, final_shard_source_value = shard_values_for_merge(rhs)
|
52
50
|
|
53
51
|
return super unless final_shard_source_value
|
54
52
|
|
55
|
-
|
53
|
+
unless final_shard_value
|
56
54
|
super
|
57
55
|
self.shard_source_value = final_shard_source_value
|
58
56
|
return self
|
@@ -61,16 +59,16 @@ module Switchman
|
|
61
59
|
return none! if final_shard_value == []
|
62
60
|
|
63
61
|
# change the primary shard if necessary before merging
|
64
|
-
if primary_shard != final_primary_shard &&
|
62
|
+
if primary_shard != final_primary_shard && rhs.primary_shard != final_primary_shard
|
65
63
|
shard!(final_primary_shard)
|
66
|
-
|
67
|
-
super(
|
64
|
+
rhs = rhs.shard(final_primary_shard)
|
65
|
+
super(rhs)
|
68
66
|
elsif primary_shard != final_primary_shard
|
69
67
|
shard!(final_primary_shard)
|
70
|
-
super(
|
71
|
-
elsif
|
72
|
-
|
73
|
-
super(
|
68
|
+
super(rhs)
|
69
|
+
elsif rhs.primary_shard != final_primary_shard
|
70
|
+
rhs = rhs.shard(final_primary_shard)
|
71
|
+
super(rhs)
|
74
72
|
else
|
75
73
|
super
|
76
74
|
end
|
@@ -7,18 +7,13 @@ module Switchman
|
|
7
7
|
def create(connection, &block)
|
8
8
|
relation = block.call ::ActiveRecord::StatementCache::Params.new
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
new(relation.arel, bind_map, relation.klass)
|
14
|
-
else
|
15
|
-
bind_map = ::ActiveRecord::StatementCache::BindMap.new(relation.bound_attributes)
|
16
|
-
new relation.arel, bind_map
|
17
|
-
end
|
10
|
+
_query_builder, binds = connection.cacheable_query(self, relation.arel)
|
11
|
+
bind_map = ::ActiveRecord::StatementCache::BindMap.new(binds)
|
12
|
+
new(relation.arel, bind_map, relation.klass)
|
18
13
|
end
|
19
14
|
end
|
20
15
|
|
21
|
-
def initialize(arel, bind_map, klass=nil)
|
16
|
+
def initialize(arel, bind_map, klass = nil)
|
22
17
|
@arel = arel
|
23
18
|
@bind_map = bind_map
|
24
19
|
@klass = klass
|
@@ -31,49 +26,39 @@ module Switchman
|
|
31
26
|
# (e.g. infer from the primary key or use the current shard)
|
32
27
|
|
33
28
|
def execute(*args)
|
34
|
-
|
35
|
-
|
36
|
-
klass = @klass
|
37
|
-
else
|
38
|
-
params, klass, connection = args
|
39
|
-
end
|
29
|
+
params, connection = args
|
30
|
+
klass = @klass
|
40
31
|
target_shard = nil
|
41
|
-
if primary_index = bind_map.primary_value_index
|
32
|
+
if (primary_index = bind_map.primary_value_index)
|
42
33
|
primary_value = params[primary_index]
|
43
34
|
target_shard = Shard.local_id_for(primary_value)[1]
|
44
35
|
end
|
45
|
-
current_shard = Shard.current(klass.
|
36
|
+
current_shard = Shard.current(klass.connection_classes)
|
46
37
|
target_shard ||= current_shard
|
47
38
|
|
48
39
|
bind_values = bind_map.bind(params, current_shard, target_shard)
|
49
40
|
|
50
|
-
target_shard.activate(klass.
|
41
|
+
target_shard.activate(klass.connection_classes) do
|
51
42
|
sql = qualified_query_builder(target_shard, klass).sql_for(bind_values, connection)
|
52
43
|
klass.find_by_sql(sql, bind_values)
|
53
44
|
end
|
54
45
|
end
|
55
46
|
|
56
|
-
|
57
|
-
|
58
|
-
@qualified_query_builders[shard.id] ||= klass.connection.cacheable_query(self.class, @arel)
|
59
|
-
end
|
60
|
-
else
|
61
|
-
def qualified_query_builder(shard, klass)
|
62
|
-
@qualified_query_builders[shard.id] ||= klass.connection.cacheable_query(self.class, @arel).first
|
63
|
-
end
|
47
|
+
def qualified_query_builder(shard, klass)
|
48
|
+
@qualified_query_builders[shard.id] ||= klass.connection.cacheable_query(self.class, @arel).first
|
64
49
|
end
|
65
50
|
|
66
51
|
module BindMap
|
67
52
|
# performs id transposition here instead of query_methods.rb
|
68
53
|
def bind(values, current_shard, target_shard)
|
69
54
|
bas = @bound_attributes.dup
|
70
|
-
@indexes.each_with_index do |offset,i|
|
55
|
+
@indexes.each_with_index do |offset, i|
|
71
56
|
ba = bas[offset]
|
72
|
-
if ba.is_a?(::ActiveRecord::Relation::QueryAttribute) && ba.value.sharded
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
57
|
+
new_value = if ba.is_a?(::ActiveRecord::Relation::QueryAttribute) && ba.value.sharded
|
58
|
+
Shard.relative_id_for(values[i], current_shard, target_shard || current_shard)
|
59
|
+
else
|
60
|
+
values[i]
|
61
|
+
end
|
77
62
|
bas[offset] = ba.with_cast_value(new_value)
|
78
63
|
end
|
79
64
|
bas
|
@@ -83,9 +68,7 @@ module Switchman
|
|
83
68
|
primary_ba_index = @bound_attributes.index do |ba|
|
84
69
|
ba.is_a?(::ActiveRecord::Relation::QueryAttribute) && ba.value.primary
|
85
70
|
end
|
86
|
-
if primary_ba_index
|
87
|
-
@indexes.index(primary_ba_index)
|
88
|
-
end
|
71
|
+
@indexes.index(primary_ba_index) if primary_ba_index
|
89
72
|
end
|
90
73
|
end
|
91
74
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Switchman
|
4
|
+
module ActiveRecord
|
5
|
+
module Tasks
|
6
|
+
module DatabaseTasks
|
7
|
+
def drop(*)
|
8
|
+
super
|
9
|
+
# no really, it's gone
|
10
|
+
Switchman.cache.delete('default_shard')
|
11
|
+
Shard.default(reload: true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -8,10 +8,8 @@ module Switchman
|
|
8
8
|
store = super
|
9
9
|
# can't use defined?, because it's a _ruby_ autoloaded constant,
|
10
10
|
# so just checking that will cause it to get required
|
11
|
-
if store.
|
12
|
-
|
13
|
-
end
|
14
|
-
store.options[:namespace] ||= lambda { Shard.current.default? ? nil : "shard_#{Shard.current.id}" }
|
11
|
+
::ActiveSupport::Cache::RedisCacheStore.prepend(RedisCacheStore) if store.instance_of?(ActiveSupport::Cache::RedisCacheStore) && !::ActiveSupport::Cache::RedisCacheStore.ancestors.include?(RedisCacheStore)
|
12
|
+
store.options[:namespace] ||= -> { Shard.current.default? ? nil : "shard_#{Shard.current.id}" }
|
15
13
|
store
|
16
14
|
end
|
17
15
|
end
|
@@ -22,7 +20,7 @@ module Switchman
|
|
22
20
|
# unfortunately, it uses the keys command, which is extraordinarily inefficient in a large redis instance
|
23
21
|
# fortunately, we can assume we control the entire instance, because we set up the namespacing, so just
|
24
22
|
# always unset it temporarily for clear calls
|
25
|
-
namespace = nil
|
23
|
+
namespace = nil # rubocop:disable Lint/ShadowedArgument
|
26
24
|
super
|
27
25
|
end
|
28
26
|
end
|