redis-memo 1.0.0 → 1.1.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/lib/redis_memo/memoizable/dependency.rb +0 -1
- data/lib/redis_memo/memoize_query/cached_select.rb +29 -33
- data/lib/redis_memo/memoize_query/cached_select/bind_params.rb +202 -70
- data/lib/redis_memo/memoize_query/cached_select/connection_adapter.rb +13 -4
- data/lib/redis_memo/options.rb +5 -0
- data/lib/redis_memo/redis.rb +0 -4
- data/lib/redis_memo/util.rb +6 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e4b5e95c92879677df377b10736e7467efa86237d90ad41254bdd7a732a8260
|
4
|
+
data.tar.gz: 9dfb62913a6cfd96e114d6526f5876696e86d1fafb6256d2454d2723449e61c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62eaf4aedb48325cc90c10cd27a3877de85a436960c78d7e1205c5dbbbe77bdb6c50ac82ea1af11d7dbd7219e7fa96cdc270b37038f1674c1fa491dffb8acec3
|
7
|
+
data.tar.gz: 2315c83ce0848d5b2f36d60e37fe60bcece24d80505ff2d7c38b1a9c0d33b8785888325410bae695abc0746a8b4663e037daec07ea83f32b6aaeafd4bf955693
|
@@ -30,7 +30,6 @@ class RedisMemo::Memoizable::Dependency
|
|
30
30
|
extracted = self.class.extract_from_relation(dependency)
|
31
31
|
nodes.merge!(extracted.nodes)
|
32
32
|
when RedisMemo::MemoizeQuery::CachedSelect::BindParams
|
33
|
-
# A private API
|
34
33
|
dependency.params.each do |model, attrs_set|
|
35
34
|
memo = model.redis_memo_class_memoizable
|
36
35
|
nodes[memo.cache_key] = memo
|
@@ -113,12 +113,7 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
113
113
|
|
114
114
|
memoize_method(
|
115
115
|
:exec_query,
|
116
|
-
method_id: proc
|
117
|
-
# replace $1 with ?,
|
118
|
-
# and (?, ?, ? ...) with (?)
|
119
|
-
sql.gsub(/(\$\d+)/, '?')
|
120
|
-
.gsub(/((, *)*\?)+/, '?')
|
121
|
-
end,
|
116
|
+
method_id: proc { |_, sql, *| RedisMemo::Util.tagify_parameterized_sql(sql) },
|
122
117
|
) do |_, sql, _, binds, **|
|
123
118
|
depends_on RedisMemo::MemoizeQuery::CachedSelect.current_query_bind_params
|
124
119
|
|
@@ -161,26 +156,30 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
161
156
|
end
|
162
157
|
|
163
158
|
# Extract bind params from the query by inspecting the SQL's AST recursively
|
164
|
-
# The bind params will be passed into the local thread variables
|
165
|
-
#
|
159
|
+
# The bind params will be passed into the local thread variables. See
|
160
|
+
# +construct_bind_params_recurse+ for how to construct binding params
|
161
|
+
# recursively.
|
166
162
|
#
|
167
163
|
# @param sql [String] SQL query
|
168
164
|
# @return [Boolean] indicating whether a query should be cached
|
169
165
|
def self.extract_bind_params(sql)
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
166
|
+
RedisMemo::Tracer.trace(
|
167
|
+
'redis_memo.memoize_query.extract_bind_params',
|
168
|
+
RedisMemo::Util.tagify_parameterized_sql(sql),
|
169
|
+
) do
|
170
|
+
ast = RedisMemo::ThreadLocalVar.arel&.ast
|
171
|
+
return false unless ast.is_a?(Arel::Nodes::SelectStatement)
|
172
|
+
return false unless ast.to_sql == sql
|
173
|
+
|
174
|
+
RedisMemo::ThreadLocalVar.substitues ||= {}
|
175
|
+
# Iterate through the Arel AST in a Depth First Search
|
176
|
+
bind_params = construct_bind_params_recurse(ast)
|
177
|
+
return false unless bind_params&.should_cache?
|
178
|
+
|
179
|
+
bind_params.extract!
|
180
|
+
RedisMemo::ThreadLocalVar.arel_bind_params = bind_params
|
181
|
+
true
|
182
|
+
end
|
184
183
|
end
|
185
184
|
|
186
185
|
def self.current_query_bind_params
|
@@ -222,7 +221,7 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
222
221
|
# @param node [Arel::Nodes::Node]
|
223
222
|
#
|
224
223
|
# @return [RedisMemo::MemoizeQuery::CachedSelect::BindParams]
|
225
|
-
def self.
|
224
|
+
def self.construct_bind_params_recurse(node)
|
226
225
|
# rubocop: disable Lint/NonLocalExitFromIterator
|
227
226
|
bind_params = BindParams.new
|
228
227
|
|
@@ -273,7 +272,7 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
273
272
|
end,
|
274
273
|
}
|
275
274
|
else
|
276
|
-
bind_params = bind_params.union(
|
275
|
+
bind_params = bind_params.union(construct_bind_params_recurse(right))
|
277
276
|
return if !bind_params
|
278
277
|
end
|
279
278
|
end
|
@@ -294,7 +293,7 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
294
293
|
return if core.wheres.empty? || binding_relation.nil?
|
295
294
|
when Arel::Nodes::TableAlias
|
296
295
|
bind_params = bind_params.union(
|
297
|
-
|
296
|
+
construct_bind_params_recurse(source_node.left),
|
298
297
|
)
|
299
298
|
|
300
299
|
return unless bind_params
|
@@ -305,7 +304,7 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
305
304
|
# Binds wheres before havings
|
306
305
|
core.wheres.each do |where|
|
307
306
|
bind_params = bind_params.union(
|
308
|
-
|
307
|
+
construct_bind_params_recurse(where),
|
309
308
|
)
|
310
309
|
|
311
310
|
return unless bind_params
|
@@ -313,26 +312,23 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
313
312
|
|
314
313
|
core.havings.each do |having|
|
315
314
|
bind_params = bind_params.union(
|
316
|
-
|
315
|
+
construct_bind_params_recurse(having),
|
317
316
|
)
|
318
317
|
|
319
318
|
return unless bind_params
|
320
319
|
end
|
321
|
-
|
322
|
-
# Reject any unbound select queries
|
323
|
-
return if binding_relation && bind_params.params[binding_relation].empty?
|
324
320
|
end
|
325
321
|
|
326
322
|
bind_params
|
327
323
|
when Arel::Nodes::Grouping
|
328
324
|
# Inline SQL
|
329
|
-
|
325
|
+
construct_bind_params_recurse(node.expr)
|
330
326
|
when Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual, Arel::Nodes::NotEqual
|
331
327
|
bind_params
|
332
328
|
when Arel::Nodes::And
|
333
329
|
node.children.each do |child|
|
334
330
|
bind_params = bind_params.product(
|
335
|
-
|
331
|
+
construct_bind_params_recurse(child),
|
336
332
|
)
|
337
333
|
|
338
334
|
return unless bind_params
|
@@ -342,7 +338,7 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
342
338
|
when Arel::Nodes::Union, Arel::Nodes::Or
|
343
339
|
[node.left, node.right].each do |child|
|
344
340
|
bind_params = bind_params.union(
|
345
|
-
|
341
|
+
construct_bind_params_recurse(child),
|
346
342
|
)
|
347
343
|
|
348
344
|
return unless bind_params
|
@@ -2,47 +2,122 @@
|
|
2
2
|
|
3
3
|
class RedisMemo::MemoizeQuery::CachedSelect
|
4
4
|
class BindParams
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
# {
|
11
|
-
# Site => [
|
12
|
-
# {name: 'a', city: 'b'},
|
13
|
-
# {name: 'a', city: 'c'},
|
14
|
-
# {name: 'b', city: 'b'},
|
15
|
-
# {name: 'b', city: 'c'},
|
16
|
-
# ],
|
17
|
-
# }
|
18
|
-
#
|
19
|
-
@params ||= Hash.new do |models, model|
|
20
|
-
models[model] = []
|
21
|
-
end
|
5
|
+
def initialize(left = nil, right = nil, operator = nil)
|
6
|
+
@left = left
|
7
|
+
@right = right
|
8
|
+
@operator = operator
|
22
9
|
end
|
23
10
|
|
24
11
|
def union(other)
|
25
12
|
return unless other
|
26
13
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
14
|
+
self.class.new(self, other, __method__)
|
15
|
+
end
|
16
|
+
|
17
|
+
def product(other)
|
18
|
+
return unless other
|
19
|
+
|
20
|
+
self.class.new(self, other, __method__)
|
21
|
+
end
|
22
|
+
|
23
|
+
def should_cache?
|
24
|
+
plan!
|
25
|
+
|
26
|
+
if plan.model_attrs.empty? || plan.dependency_size_estimation.to_i > RedisMemo::DefaultOptions.max_query_dependency_size
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
plan.model_attrs.each do |model, attrs_set|
|
31
|
+
return false if attrs_set.empty?
|
32
|
+
|
33
|
+
attrs_set.each do |attrs|
|
34
|
+
return false unless RedisMemo::MemoizeQuery
|
35
|
+
.memoized_columns(model)
|
36
|
+
.include?(attrs.keys.sort)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
+
true
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
+
#
|
44
|
+
# Extracted bind params is hash of sets: each key is a model class, each
|
45
|
+
# value is a set of hashes for memoized column conditions. Example:
|
46
|
+
#
|
47
|
+
# {
|
48
|
+
# Site => [
|
49
|
+
# {name: 'a', city: 'b'},
|
50
|
+
# {name: 'a', city: 'c'},
|
51
|
+
# {name: 'b', city: 'b'},
|
52
|
+
# {name: 'b', city: 'c'},
|
53
|
+
# ],
|
54
|
+
# }
|
55
|
+
#
|
56
|
+
def extract!
|
57
|
+
return if operator.nil?
|
58
|
+
|
59
|
+
left.extract!
|
60
|
+
right.extract!
|
61
|
+
__send__(:"#{operator}!")
|
62
|
+
end
|
63
|
+
|
64
|
+
def params
|
65
|
+
@params ||= Hash.new do |models, model|
|
66
|
+
models[model] = Set.new
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
# BindParams is built recursively when iterating through the Arel AST
|
73
|
+
# nodes. BindParams represents a binary tree. Query parameters are added to
|
74
|
+
# the leaf nodes of the tree, and the leaf nodes are connected by
|
75
|
+
# operators, such as `union` (or conditions) or `product` (and conditions).
|
76
|
+
attr_accessor :left
|
77
|
+
attr_accessor :right
|
78
|
+
attr_accessor :operator
|
79
|
+
attr_accessor :plan
|
80
|
+
|
81
|
+
def plan!
|
82
|
+
self.plan = Plan.new(self)
|
83
|
+
return if operator.nil?
|
84
|
+
|
85
|
+
left.plan!
|
86
|
+
right.plan!
|
87
|
+
__send__(:"plan_#{operator}")
|
88
|
+
end
|
89
|
+
|
90
|
+
def plan_union
|
91
|
+
plan.dependency_size_estimation = left.plan.dependency_size_estimation + right.plan.dependency_size_estimation
|
92
|
+
plan.model_attrs = union_attrs_set(left.plan.model_attrs, right.plan.model_attrs)
|
93
|
+
end
|
94
|
+
|
95
|
+
def plan_product
|
96
|
+
plan.dependency_size_estimation = left.plan.dependency_size_estimation * right.plan.dependency_size_estimation
|
97
|
+
plan.model_attrs = product_attrs_set(left.plan.model_attrs, right.plan.model_attrs)
|
98
|
+
end
|
99
|
+
|
100
|
+
def union!
|
101
|
+
@params = union_attrs_set(left.params, right.params)
|
102
|
+
end
|
103
|
+
|
104
|
+
def product!
|
105
|
+
@params = product_attrs_set(left.params, right.params)
|
106
|
+
end
|
107
|
+
|
108
|
+
def union_attrs_set(left, right)
|
109
|
+
left.merge(right) do |_, attrs_set, other_attrs_set|
|
110
|
+
next attrs_set if other_attrs_set.empty?
|
111
|
+
next other_attrs_set if attrs_set.empty?
|
112
|
+
|
113
|
+
attrs_set + other_attrs_set
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def product_attrs_set(left, right)
|
43
118
|
# Example:
|
44
119
|
#
|
45
|
-
#
|
120
|
+
# product(
|
46
121
|
# [{a: 1}, {a: 2}],
|
47
122
|
# [{b: 1}, {b: 2}],
|
48
123
|
# )
|
@@ -55,29 +130,16 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
55
130
|
# {a: 2, b: 1},
|
56
131
|
# {a: 2, b: 2},
|
57
132
|
# ]
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
# performance.
|
62
|
-
params.each do |model, attrs_set|
|
63
|
-
next if attrs_set.empty?
|
64
|
-
|
65
|
-
# The other model does not have any conditions so far: carry the
|
66
|
-
# attributes over to the other node
|
67
|
-
if other.params[model].empty?
|
68
|
-
other.params[model] = attrs_set
|
69
|
-
next
|
70
|
-
end
|
71
|
-
|
72
|
-
# Distribute the current attrs into the other
|
73
|
-
other_attrs_set_size = other.params[model].size
|
74
|
-
other_attrs_set = other.params[model]
|
75
|
-
merged_attrs_set = Array.new(other_attrs_set_size * attrs_set.size)
|
133
|
+
left.merge(right) do |_, attrs_set, other_attrs_set|
|
134
|
+
next attrs_set if other_attrs_set.empty?
|
135
|
+
next other_attrs_set if attrs_set.empty?
|
76
136
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
137
|
+
# distribute the current attrs into the other
|
138
|
+
merged_attrs_set = Set.new
|
139
|
+
attrs_set.each do |attrs|
|
140
|
+
other_attrs_set.each do |other_attrs|
|
141
|
+
merged_attrs = other_attrs.dup
|
142
|
+
should_add_attrs = true
|
81
143
|
attrs.each do |name, val|
|
82
144
|
# Conflict detected. For example:
|
83
145
|
#
|
@@ -86,42 +148,112 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
86
148
|
# Keep: a = 1 and b = 2, a = 2 and b = 1
|
87
149
|
# Discard: a = 1 and a = 2, b = 1 and b = 2
|
88
150
|
if merged_attrs.include?(name) && merged_attrs[name] != val
|
89
|
-
|
151
|
+
should_add_attrs = false
|
90
152
|
break
|
91
153
|
end
|
92
154
|
|
93
155
|
merged_attrs[name] = val
|
94
156
|
end
|
157
|
+
merged_attrs_set << merged_attrs if should_add_attrs
|
95
158
|
end
|
96
159
|
end
|
97
160
|
|
98
|
-
merged_attrs_set
|
99
|
-
other.params[model] = merged_attrs_set
|
161
|
+
merged_attrs_set
|
100
162
|
end
|
101
|
-
|
102
|
-
other
|
103
163
|
end
|
104
164
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
165
|
+
# Prior to actually extracting the bind parameters, we first quickly
|
166
|
+
# estimate if it makes sense to do so. If a query contains too many
|
167
|
+
# dependencies, or contains dependencies that have not been memoized, then
|
168
|
+
# the query itself cannot be cached correctly/efficiently, so there’s no
|
169
|
+
# point to actually extract.
|
170
|
+
#
|
171
|
+
# The planning phase is similar to the extraction phase. Though in the
|
172
|
+
# planning phase, we can ignore all the actual attribute values and only
|
173
|
+
# look at the attribute names. This way, we can precompute the dependency
|
174
|
+
# size without populating their actual values.
|
175
|
+
#
|
176
|
+
# For example, in the planning phase,
|
177
|
+
#
|
178
|
+
# {a:nil} x {b: nil} => {a: nil, b: nil}
|
179
|
+
# {a:nil, b:nil} x {a: nil: b: nil} => {a: nil, b: nil}
|
180
|
+
#
|
181
|
+
# and in the extraction phase, that's where the # of dependency can
|
182
|
+
# actually grow significantly:
|
183
|
+
#
|
184
|
+
# {a: [1,2,3]} x {b: [1,2,3]} => [{a: 1, b: 1}, ....]
|
185
|
+
# {a:[1,2], b:[1,2]} x {a: [1,2,3]: b: [1,2,3]} => [{a: 1, b: 1}, ...]
|
186
|
+
#
|
187
|
+
class Plan
|
188
|
+
class DependencySizeEstimation
|
189
|
+
def initialize(hash = nil)
|
190
|
+
@hash = hash
|
191
|
+
end
|
110
192
|
|
111
|
-
|
112
|
-
|
193
|
+
def +(other)
|
194
|
+
merged_hash = hash.dup
|
195
|
+
other.hash.each do |k, v|
|
196
|
+
merged_hash[k] += v
|
197
|
+
end
|
198
|
+
self.class.new(merged_hash)
|
199
|
+
end
|
113
200
|
|
114
|
-
|
115
|
-
|
201
|
+
def *(other)
|
202
|
+
merged_hash = hash.dup
|
203
|
+
other.hash.each do |k, v|
|
204
|
+
if merged_hash.include?(k)
|
205
|
+
merged_hash[k] *= v
|
206
|
+
else
|
207
|
+
merged_hash[k] = v
|
208
|
+
end
|
209
|
+
end
|
210
|
+
self.class.new(merged_hash)
|
211
|
+
end
|
116
212
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
213
|
+
def [](key)
|
214
|
+
hash[key]
|
215
|
+
end
|
216
|
+
|
217
|
+
def []=(key, val)
|
218
|
+
hash[key] = val
|
219
|
+
end
|
220
|
+
|
221
|
+
def to_i
|
222
|
+
ret = 0
|
223
|
+
hash.each do |_, v|
|
224
|
+
ret += v
|
225
|
+
end
|
226
|
+
ret
|
227
|
+
end
|
228
|
+
|
229
|
+
protected
|
230
|
+
|
231
|
+
def hash
|
232
|
+
@hash ||= Hash.new(0)
|
121
233
|
end
|
122
234
|
end
|
123
235
|
|
124
|
-
|
236
|
+
attr_accessor :dependency_size_estimation
|
237
|
+
attr_accessor :model_attrs
|
238
|
+
|
239
|
+
def initialize(bind_params)
|
240
|
+
@dependency_size_estimation = DependencySizeEstimation.new
|
241
|
+
@model_attrs = Hash.new do |models, model|
|
242
|
+
models[model] = Set.new
|
243
|
+
end
|
244
|
+
|
245
|
+
# An aggregated bind_params node can only obtain params by combining
|
246
|
+
# its children nodes
|
247
|
+
return if !bind_params.__send__(:operator).nil?
|
248
|
+
|
249
|
+
bind_params.params.each do |model, attrs_set|
|
250
|
+
@dependency_size_estimation[model] += attrs_set.size
|
251
|
+
attrs_set.each do |attrs|
|
252
|
+
# [k, nil]: Ignore the attr value and keep the name only
|
253
|
+
@model_attrs[model] << attrs.keys.map { |k| [k, nil] }.to_h
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
125
257
|
end
|
126
258
|
end
|
127
259
|
end
|
@@ -15,14 +15,23 @@ class RedisMemo::MemoizeQuery::CachedSelect
|
|
15
15
|
# An Arel AST in Thread local is set prior to supported query methods
|
16
16
|
if !RedisMemo.without_memoization? &&
|
17
17
|
RedisMemo::MemoizeQuery::CachedSelect.extract_bind_params(args[0])
|
18
|
+
|
19
|
+
time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
20
|
+
ret = super(*args)
|
21
|
+
time_end = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
22
|
+
|
18
23
|
# [Reids $model Load] $sql $binds
|
19
|
-
RedisMemo::DefaultOptions.logger&.
|
20
|
-
"[Redis] \u001b[36;1m#{
|
21
|
-
args[
|
24
|
+
RedisMemo::DefaultOptions.logger&.debug(
|
25
|
+
"[Redis] \u001b[36;1m#{
|
26
|
+
args[1] || 'SQL' # model name
|
27
|
+
} (#{format('%.1f', (time_end - time_start) * 1000.0)}ms) \u001b[34;1m#{
|
28
|
+
args[0] # sql
|
29
|
+
}\u001b[0m #{
|
30
|
+
args[2].map { |bind| [bind.name, bind.value_for_database] } # binds
|
22
31
|
}",
|
23
32
|
)
|
24
33
|
|
25
|
-
|
34
|
+
ret
|
26
35
|
else
|
27
36
|
RedisMemo.without_memoization { super(*args) }
|
28
37
|
end
|
data/lib/redis_memo/options.rb
CHANGED
@@ -19,6 +19,7 @@ class RedisMemo::Options
|
|
19
19
|
global_cache_key_version: nil,
|
20
20
|
expires_in: nil,
|
21
21
|
max_connection_attempts: nil,
|
22
|
+
max_query_dependency_size: 5000,
|
22
23
|
disable_all: false,
|
23
24
|
disable_cached_select: false,
|
24
25
|
disabled_models: Set.new
|
@@ -34,6 +35,7 @@ class RedisMemo::Options
|
|
34
35
|
@global_cache_key_version = global_cache_key_version
|
35
36
|
@expires_in = expires_in
|
36
37
|
@max_connection_attempts = ENV['REDIS_MEMO_MAX_ATTEMPTS_PER_REQUEST']&.to_i || max_connection_attempts
|
38
|
+
@max_query_dependency_size = ENV['REDIS_MEMO_MAX_QUERY_DEPENDENCY_SIZE']&.to_i || max_query_dependency_size
|
37
39
|
@disable_all = ENV['REDIS_MEMO_DISABLE_ALL'] == 'true' || disable_all
|
38
40
|
@disable_cached_select = ENV['REDIS_MEMO_DISABLE_CACHED_SELECT'] == 'true' || disable_cached_select
|
39
41
|
@disabled_models = disabled_models
|
@@ -162,6 +164,9 @@ class RedisMemo::Options
|
|
162
164
|
# an issue with the Redis cluster itself.
|
163
165
|
attr_accessor :max_connection_attempts
|
164
166
|
|
167
|
+
# Only cache a SQL query when the max number of dependency is smaller or equal to this number. Configurable via an ENV var REDIS_MEMO_MAX_QUERY_DEPENDENCY_SIZE. Default at 5000.
|
168
|
+
attr_accessor :max_query_dependency_size
|
169
|
+
|
165
170
|
# Passed along to the Rails {RedisCacheStore}[https://api.rubyonrails.org/classes/ActiveSupport/Cache/RedisCacheStore.html], the error handler called for Redis related errors.
|
166
171
|
attr_accessor :redis_error_handler
|
167
172
|
|
data/lib/redis_memo/redis.rb
CHANGED
@@ -17,12 +17,10 @@ class RedisMemo::Redis < Redis::Distributed
|
|
17
17
|
if option.is_a?(Array)
|
18
18
|
RedisMemo::Redis::WithReplicas.new(option)
|
19
19
|
else
|
20
|
-
option[:logger] ||= RedisMemo::DefaultOptions.logger
|
21
20
|
::Redis.new(option)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
else
|
25
|
-
options[:logger] ||= RedisMemo::DefaultOptions.logger
|
26
24
|
[::Redis.new(options)]
|
27
25
|
end
|
28
26
|
|
@@ -49,11 +47,9 @@ class RedisMemo::Redis < Redis::Distributed
|
|
49
47
|
options = orig_options.dup
|
50
48
|
primary_option = options.shift
|
51
49
|
@replicas = options.map do |option|
|
52
|
-
option[:logger] ||= RedisMemo::DefaultOptions.logger
|
53
50
|
::Redis.new(option)
|
54
51
|
end
|
55
52
|
|
56
|
-
primary_option[:logger] ||= RedisMemo::DefaultOptions.logger
|
57
53
|
super(primary_option)
|
58
54
|
end
|
59
55
|
|
data/lib/redis_memo/util.rb
CHANGED