activesupport 6.0.3.7 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +220 -533
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +3 -3
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache/file_store.rb +18 -11
- data/lib/active_support/cache/mem_cache_store.rb +143 -37
- data/lib/active_support/cache/memory_store.rb +56 -28
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +63 -88
- data/lib/active_support/cache/strategy/local_cache.rb +46 -57
- data/lib/active_support/cache.rb +273 -82
- data/lib/active_support/callbacks.rb +226 -118
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +49 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +9 -6
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +9 -7
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +21 -40
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +4 -4
- data/lib/active_support/core_ext/date/conversions.rb +5 -4
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +13 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +5 -5
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +139 -15
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash/conversions.rb +2 -2
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +2 -2
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +25 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +26 -13
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +40 -36
- data/lib/active_support/core_ext/module/introspection.rb +1 -25
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +79 -72
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +11 -0
- data/lib/active_support/core_ext/object/json.rb +42 -26
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +20 -1
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +6 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -20
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/regexp.rb +8 -1
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +39 -5
- data/lib/active_support/core_ext/string/inquiry.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +69 -45
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +26 -6
- data/lib/active_support/core_ext/time/conversions.rb +6 -3
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +4 -19
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -23
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +39 -16
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -764
- data/lib/active_support/deprecation/behaviors.rb +19 -3
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +6 -5
- data/lib/active_support/deprecation/proxy_wrappers.rb +4 -4
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +6 -1
- data/lib/active_support/descendants_tracker.rb +177 -64
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +24 -10
- data/lib/active_support/duration.rb +134 -55
- data/lib/active_support/encrypted_configuration.rb +11 -1
- data/lib/active_support/encrypted_file.rb +20 -3
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +70 -134
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +30 -4
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +51 -25
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +14 -19
- data/lib/active_support/inflector/inflections.rb +24 -9
- data/lib/active_support/inflector/methods.rb +29 -49
- data/lib/active_support/inflector/transliterate.rb +4 -4
- data/lib/active_support/isolated_execution_state.rb +56 -0
- data/lib/active_support/json/decoding.rb +4 -4
- data/lib/active_support/json/encoding.rb +8 -4
- data/lib/active_support/key_generator.rb +19 -2
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber.rb +21 -3
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +34 -21
- data/lib/active_support/message_encryptor.rb +12 -10
- data/lib/active_support/message_verifier.rb +50 -18
- data/lib/active_support/messages/metadata.rb +11 -3
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +6 -5
- data/lib/active_support/multibyte/chars.rb +13 -52
- data/lib/active_support/multibyte/unicode.rb +1 -87
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +110 -69
- data/lib/active_support/notifications/instrumenter.rb +37 -29
- data/lib/active_support/notifications.rb +47 -26
- data/lib/active_support/number_helper/number_converter.rb +2 -4
- data/lib/active_support/number_helper/number_to_currency_converter.rb +10 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -2
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +29 -16
- data/lib/active_support/option_merger.rb +9 -16
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +8 -2
- data/lib/active_support/parameter_filter.rb +21 -11
- data/lib/active_support/per_thread_registry.rb +6 -1
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +77 -5
- data/lib/active_support/rescuable.rb +6 -6
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +2 -2
- data/lib/active_support/subscriber.rb +19 -25
- data/lib/active_support/tagged_logging.rb +31 -6
- data/lib/active_support/test_case.rb +9 -21
- data/lib/active_support/testing/assertions.rb +49 -12
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +16 -95
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +53 -5
- data/lib/active_support/time_with_zone.rb +120 -55
- data/lib/active_support/values/time_zone.rb +49 -18
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +9 -2
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +29 -1
- metadata +46 -45
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -15,8 +15,7 @@ begin
|
|
15
15
|
rescue LoadError
|
16
16
|
end
|
17
17
|
|
18
|
-
require "digest
|
19
|
-
require "active_support/core_ext/marshal"
|
18
|
+
require "active_support/digest"
|
20
19
|
|
21
20
|
module ActiveSupport
|
22
21
|
module Cache
|
@@ -46,7 +45,7 @@ module ActiveSupport
|
|
46
45
|
# 4.0.1+ for distributed mget support.
|
47
46
|
# * +delete_matched+ support for Redis KEYS globs.
|
48
47
|
class RedisCacheStore < Store
|
49
|
-
# Keys are truncated with
|
48
|
+
# Keys are truncated with the ActiveSupport digest if they exceed 1kB
|
50
49
|
MAX_KEY_BYTESIZE = 1024
|
51
50
|
|
52
51
|
DEFAULT_REDIS_OPTIONS = {
|
@@ -71,35 +70,7 @@ module ActiveSupport
|
|
71
70
|
true
|
72
71
|
end
|
73
72
|
|
74
|
-
# Support raw values in the local cache strategy.
|
75
|
-
module LocalCacheWithRaw # :nodoc:
|
76
|
-
private
|
77
|
-
def write_entry(key, entry, **options)
|
78
|
-
if options[:raw] && local_cache
|
79
|
-
raw_entry = Entry.new(serialize_entry(entry, raw: true))
|
80
|
-
raw_entry.expires_at = entry.expires_at
|
81
|
-
super(key, raw_entry, **options)
|
82
|
-
else
|
83
|
-
super
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def write_multi_entries(entries, **options)
|
88
|
-
if options[:raw] && local_cache
|
89
|
-
raw_entries = entries.map do |key, entry|
|
90
|
-
raw_entry = Entry.new(serialize_entry(entry, raw: true))
|
91
|
-
raw_entry.expires_at = entry.expires_at
|
92
|
-
end.to_h
|
93
|
-
|
94
|
-
super(raw_entries, **options)
|
95
|
-
else
|
96
|
-
super
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
73
|
prepend Strategy::LocalCache
|
102
|
-
prepend LocalCacheWithRaw
|
103
74
|
|
104
75
|
class << self
|
105
76
|
# Factory method to create a new Redis instance.
|
@@ -113,7 +84,7 @@ module ActiveSupport
|
|
113
84
|
# :url String -> Redis.new(url: …)
|
114
85
|
# :url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …])
|
115
86
|
#
|
116
|
-
def build_redis(redis: nil, url: nil, **redis_options)
|
87
|
+
def build_redis(redis: nil, url: nil, **redis_options) # :nodoc:
|
117
88
|
urls = Array(url)
|
118
89
|
|
119
90
|
if redis.is_a?(Proc)
|
@@ -169,7 +140,7 @@ module ActiveSupport
|
|
169
140
|
# Race condition TTL is not set by default. This can be used to avoid
|
170
141
|
# "thundering herd" cache writes when hot cache entries are expired.
|
171
142
|
# See <tt>ActiveSupport::Cache::Store#fetch</tt> for more.
|
172
|
-
def initialize(namespace: nil, compress: true, compress_threshold: 1.kilobyte, expires_in: nil, race_condition_ttl: nil, error_handler: DEFAULT_ERROR_HANDLER, **redis_options)
|
143
|
+
def initialize(namespace: nil, compress: true, compress_threshold: 1.kilobyte, coder: default_coder, expires_in: nil, race_condition_ttl: nil, error_handler: DEFAULT_ERROR_HANDLER, **redis_options)
|
173
144
|
@redis_options = redis_options
|
174
145
|
|
175
146
|
@max_key_bytesize = MAX_KEY_BYTESIZE
|
@@ -177,7 +148,8 @@ module ActiveSupport
|
|
177
148
|
|
178
149
|
super namespace: namespace,
|
179
150
|
compress: compress, compress_threshold: compress_threshold,
|
180
|
-
expires_in: expires_in, race_condition_ttl: race_condition_ttl
|
151
|
+
expires_in: expires_in, race_condition_ttl: race_condition_ttl,
|
152
|
+
coder: coder
|
181
153
|
end
|
182
154
|
|
183
155
|
def redis
|
@@ -195,7 +167,7 @@ module ActiveSupport
|
|
195
167
|
|
196
168
|
def inspect
|
197
169
|
instance = @redis || @redis_options
|
198
|
-
"
|
170
|
+
"#<#{self.class} options=#{options.inspect} redis=#{instance.inspect}>"
|
199
171
|
end
|
200
172
|
|
201
173
|
# Cache Store API implementation.
|
@@ -238,10 +210,14 @@ module ActiveSupport
|
|
238
210
|
pattern = namespace_key(matcher, options)
|
239
211
|
cursor = "0"
|
240
212
|
# Fetch keys in batches using SCAN to avoid blocking the Redis server.
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
213
|
+
nodes = c.respond_to?(:nodes) ? c.nodes : [c]
|
214
|
+
|
215
|
+
nodes.each do |node|
|
216
|
+
begin
|
217
|
+
cursor, keys = node.scan(cursor, match: pattern, count: SCAN_BATCH_SIZE)
|
218
|
+
node.del(*keys) unless keys.empty?
|
219
|
+
end until cursor == "0"
|
220
|
+
end
|
245
221
|
end
|
246
222
|
end
|
247
223
|
end
|
@@ -314,12 +290,17 @@ module ActiveSupport
|
|
314
290
|
end
|
315
291
|
end
|
316
292
|
|
317
|
-
|
293
|
+
# Get info from redis servers.
|
294
|
+
def stats
|
295
|
+
redis.with { |c| c.info }
|
296
|
+
end
|
297
|
+
|
298
|
+
def mget_capable? # :nodoc:
|
318
299
|
set_redis_capabilities unless defined? @mget_capable
|
319
300
|
@mget_capable
|
320
301
|
end
|
321
302
|
|
322
|
-
def mset_capable?
|
303
|
+
def mset_capable? # :nodoc:
|
323
304
|
set_redis_capabilities unless defined? @mset_capable
|
324
305
|
@mset_capable
|
325
306
|
end
|
@@ -339,15 +320,18 @@ module ActiveSupport
|
|
339
320
|
# Store provider interface:
|
340
321
|
# Read an entry from the cache.
|
341
322
|
def read_entry(key, **options)
|
323
|
+
deserialize_entry(read_serialized_entry(key, **options), **options)
|
324
|
+
end
|
325
|
+
|
326
|
+
def read_serialized_entry(key, raw: false, **options)
|
342
327
|
failsafe :read_entry do
|
343
|
-
|
344
|
-
deserialize_entry(redis.with { |c| c.get(key) }, raw: raw)
|
328
|
+
redis.with { |c| c.get(key) }
|
345
329
|
end
|
346
330
|
end
|
347
331
|
|
348
332
|
def read_multi_entries(names, **options)
|
349
333
|
if mget_capable?
|
350
|
-
read_multi_mget(*names)
|
334
|
+
read_multi_mget(*names, **options)
|
351
335
|
else
|
352
336
|
super
|
353
337
|
end
|
@@ -378,9 +362,11 @@ module ActiveSupport
|
|
378
362
|
# Write an entry to the cache.
|
379
363
|
#
|
380
364
|
# Requires Redis 2.6.12+ for extended SET options.
|
381
|
-
def write_entry(key, entry,
|
382
|
-
|
365
|
+
def write_entry(key, entry, raw: false, **options)
|
366
|
+
write_serialized_entry(key, serialize_entry(entry, raw: raw, **options), raw: raw, **options)
|
367
|
+
end
|
383
368
|
|
369
|
+
def write_serialized_entry(key, payload, raw: false, unless_exist: false, expires_in: nil, race_condition_ttl: nil, **options)
|
384
370
|
# If race condition TTL is in use, ensure that cache entries
|
385
371
|
# stick around a bit longer after they would have expired
|
386
372
|
# so we can purposefully serve stale entries.
|
@@ -388,16 +374,14 @@ module ActiveSupport
|
|
388
374
|
expires_in += 5.minutes
|
389
375
|
end
|
390
376
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
377
|
+
modifiers = {}
|
378
|
+
if unless_exist || expires_in
|
379
|
+
modifiers[:nx] = unless_exist
|
380
|
+
modifiers[:px] = (1000 * expires_in.to_f).ceil if expires_in
|
381
|
+
end
|
396
382
|
|
397
|
-
|
398
|
-
|
399
|
-
redis.with { |c| c.set key, serialized_entry }
|
400
|
-
end
|
383
|
+
failsafe :write_entry, returning: false do
|
384
|
+
redis.with { |c| c.set key, payload, **modifiers }
|
401
385
|
end
|
402
386
|
end
|
403
387
|
|
@@ -414,12 +398,20 @@ module ActiveSupport
|
|
414
398
|
end
|
415
399
|
end
|
416
400
|
|
401
|
+
# Deletes multiple entries in the cache. Returns the number of entries deleted.
|
402
|
+
def delete_multi_entries(entries, **_options)
|
403
|
+
redis.with { |c| c.del(entries) }
|
404
|
+
end
|
405
|
+
|
417
406
|
# Nonstandard store provider API to write multiple values at once.
|
418
407
|
def write_multi_entries(entries, expires_in: nil, **options)
|
419
408
|
if entries.any?
|
420
409
|
if mset_capable? && expires_in.nil?
|
421
410
|
failsafe :write_multi_entries do
|
422
|
-
|
411
|
+
payload = serialize_entries(entries, **options)
|
412
|
+
redis.with do |c|
|
413
|
+
c.mapped_mset(payload)
|
414
|
+
end
|
423
415
|
end
|
424
416
|
else
|
425
417
|
super
|
@@ -429,12 +421,12 @@ module ActiveSupport
|
|
429
421
|
|
430
422
|
# Truncate keys that exceed 1kB.
|
431
423
|
def normalize_key(key, options)
|
432
|
-
truncate_key super
|
424
|
+
truncate_key super&.b
|
433
425
|
end
|
434
426
|
|
435
427
|
def truncate_key(key)
|
436
|
-
if key.bytesize > max_key_bytesize
|
437
|
-
suffix = ":
|
428
|
+
if key && key.bytesize > max_key_bytesize
|
429
|
+
suffix = ":hash:#{ActiveSupport::Digest.hexdigest(key)}"
|
438
430
|
truncate_at = max_key_bytesize - suffix.bytesize
|
439
431
|
"#{key.byteslice(0, truncate_at)}#{suffix}"
|
440
432
|
else
|
@@ -442,52 +434,35 @@ module ActiveSupport
|
|
442
434
|
end
|
443
435
|
end
|
444
436
|
|
445
|
-
def deserialize_entry(
|
446
|
-
if
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
if raw != written_raw
|
451
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
452
|
-
Using a different value for the raw option when reading and writing
|
453
|
-
to a cache key is deprecated for :redis_cache_store and Rails 6.0
|
454
|
-
will stop automatically detecting the format when reading to avoid
|
455
|
-
marshal loading untrusted raw strings.
|
456
|
-
MSG
|
457
|
-
end
|
458
|
-
|
459
|
-
entry.is_a?(Entry) ? entry : Entry.new(entry)
|
437
|
+
def deserialize_entry(payload, raw: false, **)
|
438
|
+
if raw && !payload.nil?
|
439
|
+
Entry.new(payload)
|
440
|
+
else
|
441
|
+
super(payload)
|
460
442
|
end
|
461
443
|
end
|
462
444
|
|
463
|
-
def serialize_entry(entry, raw: false)
|
445
|
+
def serialize_entry(entry, raw: false, **options)
|
464
446
|
if raw
|
465
447
|
entry.value.to_s
|
466
448
|
else
|
467
|
-
|
449
|
+
super(entry, raw: raw, **options)
|
468
450
|
end
|
469
451
|
end
|
470
452
|
|
471
|
-
def serialize_entries(entries,
|
453
|
+
def serialize_entries(entries, **options)
|
472
454
|
entries.transform_values do |entry|
|
473
|
-
serialize_entry
|
455
|
+
serialize_entry(entry, **options)
|
474
456
|
end
|
475
457
|
end
|
476
458
|
|
477
459
|
def failsafe(method, returning: nil)
|
478
460
|
yield
|
479
|
-
rescue ::Redis::BaseError =>
|
480
|
-
|
461
|
+
rescue ::Redis::BaseError => error
|
462
|
+
ActiveSupport.error_reporter&.report(error, handled: true, severity: :warning)
|
463
|
+
@error_handler&.call(method: method, exception: error, returning: returning)
|
481
464
|
returning
|
482
465
|
end
|
483
|
-
|
484
|
-
def handle_exception(exception:, method:, returning:)
|
485
|
-
if @error_handler
|
486
|
-
@error_handler.(method: method, exception: exception, returning: returning)
|
487
|
-
end
|
488
|
-
rescue => failsafe
|
489
|
-
warn "RedisCacheStore ignored exception in handle_exception: #{failsafe.class}: #{failsafe.message}\n #{failsafe.backtrace.join("\n ")}"
|
490
|
-
end
|
491
466
|
end
|
492
467
|
end
|
493
468
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/object/duplicable"
|
4
3
|
require "active_support/core_ext/string/inflections"
|
5
|
-
require "active_support/per_thread_registry"
|
6
4
|
|
7
5
|
module ActiveSupport
|
8
6
|
module Cache
|
@@ -14,74 +12,56 @@ module ActiveSupport
|
|
14
12
|
autoload :Middleware, "active_support/cache/strategy/local_cache_middleware"
|
15
13
|
|
16
14
|
# Class for storing and registering the local caches.
|
17
|
-
|
18
|
-
extend
|
19
|
-
|
20
|
-
def initialize
|
21
|
-
@registry = {}
|
22
|
-
end
|
15
|
+
module LocalCacheRegistry # :nodoc:
|
16
|
+
extend self
|
23
17
|
|
24
18
|
def cache_for(local_cache_key)
|
25
|
-
|
19
|
+
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
|
20
|
+
registry[local_cache_key]
|
26
21
|
end
|
27
22
|
|
28
23
|
def set_cache_for(local_cache_key, value)
|
29
|
-
|
24
|
+
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
|
25
|
+
registry[local_cache_key] = value
|
30
26
|
end
|
31
|
-
|
32
|
-
def self.set_cache_for(l, v); instance.set_cache_for l, v; end
|
33
|
-
def self.cache_for(l); instance.cache_for l; end
|
34
27
|
end
|
35
28
|
|
36
29
|
# Simple memory backed cache. This cache is not thread safe and is intended only
|
37
30
|
# for serving as a temporary memory cache for a single thread.
|
38
|
-
class LocalStore
|
31
|
+
class LocalStore
|
39
32
|
def initialize
|
40
|
-
super
|
41
33
|
@data = {}
|
42
34
|
end
|
43
35
|
|
44
|
-
# Don't allow synchronizing since it isn't thread safe.
|
45
|
-
def synchronize # :nodoc:
|
46
|
-
yield
|
47
|
-
end
|
48
|
-
|
49
36
|
def clear(options = nil)
|
50
37
|
@data.clear
|
51
38
|
end
|
52
39
|
|
53
|
-
def read_entry(key
|
40
|
+
def read_entry(key)
|
54
41
|
@data[key]
|
55
42
|
end
|
56
43
|
|
57
|
-
def read_multi_entries(keys
|
58
|
-
|
59
|
-
|
60
|
-
keys.each do |name|
|
61
|
-
entry = read_entry(name, **options)
|
62
|
-
values[name] = entry.value if entry
|
63
|
-
end
|
64
|
-
|
65
|
-
values
|
44
|
+
def read_multi_entries(keys)
|
45
|
+
@data.slice(*keys)
|
66
46
|
end
|
67
47
|
|
68
|
-
def write_entry(key,
|
69
|
-
@data[key] =
|
48
|
+
def write_entry(key, entry)
|
49
|
+
@data[key] = entry
|
70
50
|
true
|
71
51
|
end
|
72
52
|
|
73
|
-
def delete_entry(key
|
53
|
+
def delete_entry(key)
|
74
54
|
!!@data.delete(key)
|
75
55
|
end
|
76
56
|
|
77
|
-
def fetch_entry(key
|
57
|
+
def fetch_entry(key) # :nodoc:
|
78
58
|
@data.fetch(key) { @data[key] = yield }
|
79
59
|
end
|
80
60
|
end
|
81
61
|
|
82
62
|
# Use a local cache for the duration of block.
|
83
|
-
def with_local_cache
|
84
|
-
use_temporary_local_cache(LocalStore.new)
|
63
|
+
def with_local_cache(&block)
|
64
|
+
use_temporary_local_cache(LocalStore.new, &block)
|
85
65
|
end
|
86
66
|
|
87
67
|
# Middleware class can be inserted as a Rack handler to be local cache for the
|
@@ -104,24 +84,36 @@ module ActiveSupport
|
|
104
84
|
super
|
105
85
|
end
|
106
86
|
|
87
|
+
def delete_matched(matcher, options = nil) # :nodoc:
|
88
|
+
return super unless cache = local_cache
|
89
|
+
cache.clear
|
90
|
+
super
|
91
|
+
end
|
92
|
+
|
107
93
|
def increment(name, amount = 1, **options) # :nodoc:
|
108
94
|
return super unless local_cache
|
109
95
|
value = bypass_local_cache { super }
|
110
|
-
write_cache_value(name, value, **options)
|
96
|
+
write_cache_value(name, value, raw: true, **options)
|
111
97
|
value
|
112
98
|
end
|
113
99
|
|
114
100
|
def decrement(name, amount = 1, **options) # :nodoc:
|
115
101
|
return super unless local_cache
|
116
102
|
value = bypass_local_cache { super }
|
117
|
-
write_cache_value(name, value, **options)
|
103
|
+
write_cache_value(name, value, raw: true, **options)
|
118
104
|
value
|
119
105
|
end
|
120
106
|
|
121
107
|
private
|
122
|
-
def
|
108
|
+
def read_serialized_entry(key, raw: false, **options)
|
123
109
|
if cache = local_cache
|
124
|
-
|
110
|
+
hit = true
|
111
|
+
entry = cache.fetch_entry(key) do
|
112
|
+
hit = false
|
113
|
+
super
|
114
|
+
end
|
115
|
+
options[:event][:store] = cache.class.name if hit && options[:event]
|
116
|
+
entry
|
125
117
|
else
|
126
118
|
super
|
127
119
|
end
|
@@ -130,7 +122,7 @@ module ActiveSupport
|
|
130
122
|
def read_multi_entries(keys, **options)
|
131
123
|
return super unless local_cache
|
132
124
|
|
133
|
-
local_entries = local_cache.read_multi_entries(keys
|
125
|
+
local_entries = local_cache.read_multi_entries(keys)
|
134
126
|
missed_keys = keys - local_entries.keys
|
135
127
|
|
136
128
|
if missed_keys.any?
|
@@ -140,30 +132,27 @@ module ActiveSupport
|
|
140
132
|
end
|
141
133
|
end
|
142
134
|
|
143
|
-
def
|
144
|
-
if
|
145
|
-
local_cache.
|
135
|
+
def write_serialized_entry(key, payload, **)
|
136
|
+
if return_value = super
|
137
|
+
local_cache.write_entry(key, payload) if local_cache
|
146
138
|
else
|
147
|
-
local_cache.
|
139
|
+
local_cache.delete_entry(key) if local_cache
|
148
140
|
end
|
149
|
-
|
150
|
-
super
|
141
|
+
return_value
|
151
142
|
end
|
152
143
|
|
153
|
-
def delete_entry(key, **
|
154
|
-
local_cache.delete_entry(key
|
144
|
+
def delete_entry(key, **)
|
145
|
+
local_cache.delete_entry(key) if local_cache
|
155
146
|
super
|
156
147
|
end
|
157
148
|
|
158
149
|
def write_cache_value(name, value, **options)
|
159
150
|
name = normalize_key(name, options)
|
160
151
|
cache = local_cache
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
cache.delete(name, **options)
|
166
|
-
end
|
152
|
+
if value
|
153
|
+
cache.write_entry(name, serialize_entry(new_entry(value, **options), **options))
|
154
|
+
else
|
155
|
+
cache.delete_entry(name)
|
167
156
|
end
|
168
157
|
end
|
169
158
|
|
@@ -175,8 +164,8 @@ module ActiveSupport
|
|
175
164
|
LocalCacheRegistry.cache_for(local_cache_key)
|
176
165
|
end
|
177
166
|
|
178
|
-
def bypass_local_cache
|
179
|
-
use_temporary_local_cache(nil)
|
167
|
+
def bypass_local_cache(&block)
|
168
|
+
use_temporary_local_cache(nil, &block)
|
180
169
|
end
|
181
170
|
|
182
171
|
def use_temporary_local_cache(temporary_cache)
|