activesupport 6.1.0 → 7.0.4.1
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 +263 -352
- 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 +0 -2
- data/lib/active_support/backtrace_cleaner.rb +2 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +16 -10
- data/lib/active_support/cache/mem_cache_store.rb +154 -39
- data/lib/active_support/cache/memory_store.rb +24 -16
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +59 -78
- data/lib/active_support/cache/strategy/local_cache.rb +38 -61
- data/lib/active_support/cache.rb +306 -148
- data/lib/active_support/callbacks.rb +184 -85
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +5 -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 +8 -5
- data/lib/active_support/configuration_file.rb +7 -2
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +13 -12
- 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/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +25 -17
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +9 -9
- data/lib/active_support/core_ext/date/conversions.rb +14 -14
- 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 +4 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- 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 +101 -32
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +0 -1
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
- 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/acts_like.rb +29 -5
- 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 +37 -25
- 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 +0 -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 -25
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -1
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +91 -39
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +9 -7
- data/lib/active_support/core_ext/time/conversions.rb +14 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +7 -22
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -27
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes.rb +32 -14
- 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 -788
- data/lib/active_support/deprecation/behaviors.rb +8 -5
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +174 -68
- 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 +9 -1
- data/lib/active_support/duration.rb +81 -51
- data/lib/active_support/encrypted_configuration.rb +13 -2
- data/lib/active_support/encrypted_file.rb +13 -1
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +3 -5
- 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 +43 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +19 -10
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +9 -2
- 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 +1 -1
- data/lib/active_support/inflector/inflections.rb +23 -7
- data/lib/active_support/inflector/methods.rb +24 -48
- data/lib/active_support/inflector/transliterate.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +22 -5
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +2 -2
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +15 -5
- data/lib/active_support/logger_thread_safe_level.rb +4 -13
- data/lib/active_support/message_encryptor.rb +12 -6
- data/lib/active_support/message_verifier.rb +46 -14
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +91 -65
- data/lib/active_support/notifications/instrumenter.rb +32 -15
- data/lib/active_support/notifications.rb +24 -24
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +10 -6
- data/lib/active_support/number_helper/rounding_helper.rb +2 -6
- data/lib/active_support/number_helper.rb +0 -2
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +6 -1
- data/lib/active_support/per_thread_registry.rb +5 -0
- data/lib/active_support/railtie.rb +69 -19
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +16 -16
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +2 -2
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +7 -18
- data/lib/active_support/tagged_logging.rb +2 -2
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +36 -6
- 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 +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- 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 +13 -2
- data/lib/active_support/time_with_zone.rb +60 -20
- data/lib/active_support/values/time_zone.rb +36 -15
- data/lib/active_support/version.rb +1 -1
- 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 +1 -1
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +17 -1
- metadata +29 -26
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -5,18 +5,21 @@ begin
|
|
5
5
|
require "redis"
|
6
6
|
require "redis/distributed"
|
7
7
|
rescue LoadError
|
8
|
-
warn "The Redis cache store requires the redis gem, version 4.0.1 or later. Please add it to your Gemfile: `gem \"redis\", \"
|
8
|
+
warn "The Redis cache store requires the redis gem, version 4.0.1 or later. Please add it to your Gemfile: `gem \"redis\", \">= 4.0.1\"`"
|
9
9
|
raise
|
10
10
|
end
|
11
11
|
|
12
12
|
# Prefer the hiredis driver but don't require it.
|
13
13
|
begin
|
14
|
-
|
14
|
+
if ::Redis::VERSION < "5"
|
15
|
+
require "redis/connection/hiredis"
|
16
|
+
else
|
17
|
+
require "hiredis-client"
|
18
|
+
end
|
15
19
|
rescue LoadError
|
16
20
|
end
|
17
21
|
|
18
|
-
require "digest
|
19
|
-
require "active_support/core_ext/marshal"
|
22
|
+
require "active_support/digest"
|
20
23
|
|
21
24
|
module ActiveSupport
|
22
25
|
module Cache
|
@@ -46,7 +49,7 @@ module ActiveSupport
|
|
46
49
|
# 4.0.1+ for distributed mget support.
|
47
50
|
# * +delete_matched+ support for Redis KEYS globs.
|
48
51
|
class RedisCacheStore < Store
|
49
|
-
# Keys are truncated with
|
52
|
+
# Keys are truncated with the ActiveSupport digest if they exceed 1kB
|
50
53
|
MAX_KEY_BYTESIZE = 1024
|
51
54
|
|
52
55
|
DEFAULT_REDIS_OPTIONS = {
|
@@ -71,35 +74,7 @@ module ActiveSupport
|
|
71
74
|
true
|
72
75
|
end
|
73
76
|
|
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
77
|
prepend Strategy::LocalCache
|
102
|
-
prepend LocalCacheWithRaw
|
103
78
|
|
104
79
|
class << self
|
105
80
|
# Factory method to create a new Redis instance.
|
@@ -113,7 +88,7 @@ module ActiveSupport
|
|
113
88
|
# :url String -> Redis.new(url: …)
|
114
89
|
# :url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …])
|
115
90
|
#
|
116
|
-
def build_redis(redis: nil, url: nil, **redis_options)
|
91
|
+
def build_redis(redis: nil, url: nil, **redis_options) # :nodoc:
|
117
92
|
urls = Array(url)
|
118
93
|
|
119
94
|
if redis.is_a?(Proc)
|
@@ -121,9 +96,11 @@ module ActiveSupport
|
|
121
96
|
elsif redis
|
122
97
|
redis
|
123
98
|
elsif urls.size > 1
|
124
|
-
build_redis_distributed_client
|
99
|
+
build_redis_distributed_client(urls: urls, **redis_options)
|
100
|
+
elsif urls.empty?
|
101
|
+
build_redis_client(**redis_options)
|
125
102
|
else
|
126
|
-
build_redis_client
|
103
|
+
build_redis_client(url: urls.first, **redis_options)
|
127
104
|
end
|
128
105
|
end
|
129
106
|
|
@@ -134,8 +111,8 @@ module ActiveSupport
|
|
134
111
|
end
|
135
112
|
end
|
136
113
|
|
137
|
-
def build_redis_client(
|
138
|
-
::Redis.new
|
114
|
+
def build_redis_client(**redis_options)
|
115
|
+
::Redis.new(DEFAULT_REDIS_OPTIONS.merge(redis_options))
|
139
116
|
end
|
140
117
|
end
|
141
118
|
|
@@ -168,8 +145,8 @@ module ActiveSupport
|
|
168
145
|
#
|
169
146
|
# Race condition TTL is not set by default. This can be used to avoid
|
170
147
|
# "thundering herd" cache writes when hot cache entries are expired.
|
171
|
-
# See
|
172
|
-
def initialize(namespace: nil, compress: true, compress_threshold: 1.kilobyte, coder:
|
148
|
+
# See ActiveSupport::Cache::Store#fetch for more.
|
149
|
+
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
150
|
@redis_options = redis_options
|
174
151
|
|
175
152
|
@max_key_bytesize = MAX_KEY_BYTESIZE
|
@@ -254,8 +231,8 @@ module ActiveSupport
|
|
254
231
|
# Cache Store API implementation.
|
255
232
|
#
|
256
233
|
# Increment a cached value. This method uses the Redis incr atomic
|
257
|
-
# operator and can only be used on values written with the
|
258
|
-
# Calling it on a value not stored with
|
234
|
+
# operator and can only be used on values written with the +:raw+ option.
|
235
|
+
# Calling it on a value not stored with +:raw+ will initialize that value
|
259
236
|
# to zero.
|
260
237
|
#
|
261
238
|
# Failsafe: Raises errors.
|
@@ -277,8 +254,8 @@ module ActiveSupport
|
|
277
254
|
# Cache Store API implementation.
|
278
255
|
#
|
279
256
|
# Decrement a cached value. This method uses the Redis decr atomic
|
280
|
-
# operator and can only be used on values written with the
|
281
|
-
# Calling it on a value not stored with
|
257
|
+
# operator and can only be used on values written with the +:raw+ option.
|
258
|
+
# Calling it on a value not stored with +:raw+ will initialize that value
|
282
259
|
# to zero.
|
283
260
|
#
|
284
261
|
# Failsafe: Raises errors.
|
@@ -319,12 +296,17 @@ module ActiveSupport
|
|
319
296
|
end
|
320
297
|
end
|
321
298
|
|
322
|
-
|
299
|
+
# Get info from redis servers.
|
300
|
+
def stats
|
301
|
+
redis.with { |c| c.info }
|
302
|
+
end
|
303
|
+
|
304
|
+
def mget_capable? # :nodoc:
|
323
305
|
set_redis_capabilities unless defined? @mget_capable
|
324
306
|
@mget_capable
|
325
307
|
end
|
326
308
|
|
327
|
-
def mset_capable?
|
309
|
+
def mset_capable? # :nodoc:
|
328
310
|
set_redis_capabilities unless defined? @mset_capable
|
329
311
|
@mset_capable
|
330
312
|
end
|
@@ -344,9 +326,12 @@ module ActiveSupport
|
|
344
326
|
# Store provider interface:
|
345
327
|
# Read an entry from the cache.
|
346
328
|
def read_entry(key, **options)
|
329
|
+
deserialize_entry(read_serialized_entry(key, **options), **options)
|
330
|
+
end
|
331
|
+
|
332
|
+
def read_serialized_entry(key, raw: false, **options)
|
347
333
|
failsafe :read_entry do
|
348
|
-
|
349
|
-
deserialize_entry(redis.with { |c| c.get(key) }, raw: raw)
|
334
|
+
redis.with { |c| c.get(key) }
|
350
335
|
end
|
351
336
|
end
|
352
337
|
|
@@ -383,9 +368,11 @@ module ActiveSupport
|
|
383
368
|
# Write an entry to the cache.
|
384
369
|
#
|
385
370
|
# Requires Redis 2.6.12+ for extended SET options.
|
386
|
-
def write_entry(key, entry,
|
387
|
-
|
371
|
+
def write_entry(key, entry, raw: false, **options)
|
372
|
+
write_serialized_entry(key, serialize_entry(entry, raw: raw, **options), raw: raw, **options)
|
373
|
+
end
|
388
374
|
|
375
|
+
def write_serialized_entry(key, payload, raw: false, unless_exist: false, expires_in: nil, race_condition_ttl: nil, **options)
|
389
376
|
# If race condition TTL is in use, ensure that cache entries
|
390
377
|
# stick around a bit longer after they would have expired
|
391
378
|
# so we can purposefully serve stale entries.
|
@@ -393,16 +380,14 @@ module ActiveSupport
|
|
393
380
|
expires_in += 5.minutes
|
394
381
|
end
|
395
382
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
383
|
+
modifiers = {}
|
384
|
+
if unless_exist || expires_in
|
385
|
+
modifiers[:nx] = unless_exist
|
386
|
+
modifiers[:px] = (1000 * expires_in.to_f).ceil if expires_in
|
387
|
+
end
|
401
388
|
|
402
|
-
|
403
|
-
|
404
|
-
redis.with { |c| c.set key, serialized_entry }
|
405
|
-
end
|
389
|
+
failsafe :write_entry, returning: false do
|
390
|
+
redis.with { |c| c.set key, payload, **modifiers }
|
406
391
|
end
|
407
392
|
end
|
408
393
|
|
@@ -429,7 +414,10 @@ module ActiveSupport
|
|
429
414
|
if entries.any?
|
430
415
|
if mset_capable? && expires_in.nil?
|
431
416
|
failsafe :write_multi_entries do
|
432
|
-
|
417
|
+
payload = serialize_entries(entries, **options)
|
418
|
+
redis.with do |c|
|
419
|
+
c.mapped_mset(payload)
|
420
|
+
end
|
433
421
|
end
|
434
422
|
else
|
435
423
|
super
|
@@ -444,7 +432,7 @@ module ActiveSupport
|
|
444
432
|
|
445
433
|
def truncate_key(key)
|
446
434
|
if key && key.bytesize > max_key_bytesize
|
447
|
-
suffix = ":
|
435
|
+
suffix = ":hash:#{ActiveSupport::Digest.hexdigest(key)}"
|
448
436
|
truncate_at = max_key_bytesize - suffix.bytesize
|
449
437
|
"#{key.byteslice(0, truncate_at)}#{suffix}"
|
450
438
|
else
|
@@ -452,42 +440,35 @@ module ActiveSupport
|
|
452
440
|
end
|
453
441
|
end
|
454
442
|
|
455
|
-
def deserialize_entry(payload, raw:)
|
456
|
-
if
|
457
|
-
Entry.new(payload
|
443
|
+
def deserialize_entry(payload, raw: false, **)
|
444
|
+
if raw && !payload.nil?
|
445
|
+
Entry.new(payload)
|
458
446
|
else
|
459
447
|
super(payload)
|
460
448
|
end
|
461
449
|
end
|
462
450
|
|
463
|
-
def serialize_entry(entry, raw: false)
|
451
|
+
def serialize_entry(entry, raw: false, **options)
|
464
452
|
if raw
|
465
453
|
entry.value.to_s
|
466
454
|
else
|
467
|
-
super(entry)
|
455
|
+
super(entry, raw: raw, **options)
|
468
456
|
end
|
469
457
|
end
|
470
458
|
|
471
|
-
def serialize_entries(entries,
|
459
|
+
def serialize_entries(entries, **options)
|
472
460
|
entries.transform_values do |entry|
|
473
|
-
serialize_entry
|
461
|
+
serialize_entry(entry, **options)
|
474
462
|
end
|
475
463
|
end
|
476
464
|
|
477
465
|
def failsafe(method, returning: nil)
|
478
466
|
yield
|
479
|
-
rescue ::Redis::BaseError =>
|
480
|
-
|
467
|
+
rescue ::Redis::BaseError => error
|
468
|
+
ActiveSupport.error_reporter&.report(error, handled: true, severity: :warning)
|
469
|
+
@error_handler&.call(method: method, exception: error, returning: returning)
|
481
470
|
returning
|
482
471
|
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
472
|
end
|
492
473
|
end
|
493
474
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/string/inflections"
|
4
|
-
require "active_support/per_thread_registry"
|
5
4
|
|
6
5
|
module ActiveSupport
|
7
6
|
module Cache
|
@@ -13,78 +12,56 @@ module ActiveSupport
|
|
13
12
|
autoload :Middleware, "active_support/cache/strategy/local_cache_middleware"
|
14
13
|
|
15
14
|
# Class for storing and registering the local caches.
|
16
|
-
|
17
|
-
extend
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
@registry = {}
|
21
|
-
end
|
15
|
+
module LocalCacheRegistry # :nodoc:
|
16
|
+
extend self
|
22
17
|
|
23
18
|
def cache_for(local_cache_key)
|
24
|
-
|
19
|
+
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
|
20
|
+
registry[local_cache_key]
|
25
21
|
end
|
26
22
|
|
27
23
|
def set_cache_for(local_cache_key, value)
|
28
|
-
|
24
|
+
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
|
25
|
+
registry[local_cache_key] = value
|
29
26
|
end
|
30
|
-
|
31
|
-
def self.set_cache_for(l, v); instance.set_cache_for l, v; end
|
32
|
-
def self.cache_for(l); instance.cache_for l; end
|
33
27
|
end
|
34
28
|
|
35
29
|
# Simple memory backed cache. This cache is not thread safe and is intended only
|
36
30
|
# for serving as a temporary memory cache for a single thread.
|
37
|
-
class LocalStore
|
31
|
+
class LocalStore
|
38
32
|
def initialize
|
39
|
-
super
|
40
33
|
@data = {}
|
41
34
|
end
|
42
35
|
|
43
|
-
# Don't allow synchronizing since it isn't thread safe.
|
44
|
-
def synchronize # :nodoc:
|
45
|
-
yield
|
46
|
-
end
|
47
|
-
|
48
36
|
def clear(options = nil)
|
49
37
|
@data.clear
|
50
38
|
end
|
51
39
|
|
52
|
-
def read_entry(key
|
40
|
+
def read_entry(key)
|
53
41
|
@data[key]
|
54
42
|
end
|
55
43
|
|
56
|
-
def read_multi_entries(keys
|
57
|
-
|
58
|
-
|
59
|
-
keys.each do |name|
|
60
|
-
entry = read_entry(name, **options)
|
61
|
-
values[name] = entry.value if entry
|
62
|
-
end
|
63
|
-
|
64
|
-
values
|
44
|
+
def read_multi_entries(keys)
|
45
|
+
@data.slice(*keys)
|
65
46
|
end
|
66
47
|
|
67
|
-
def write_entry(key, entry
|
68
|
-
entry.dup_value!
|
48
|
+
def write_entry(key, entry)
|
69
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
|
78
|
-
|
79
|
-
dup_entry = entry.dup
|
80
|
-
dup_entry&.dup_value!
|
81
|
-
dup_entry
|
57
|
+
def fetch_entry(key) # :nodoc:
|
58
|
+
@data.fetch(key) { @data[key] = yield }
|
82
59
|
end
|
83
60
|
end
|
84
61
|
|
85
62
|
# Use a local cache for the duration of block.
|
86
|
-
def with_local_cache
|
87
|
-
use_temporary_local_cache(LocalStore.new)
|
63
|
+
def with_local_cache(&block)
|
64
|
+
use_temporary_local_cache(LocalStore.new, &block)
|
88
65
|
end
|
89
66
|
|
90
67
|
# Middleware class can be inserted as a Rack handler to be local cache for the
|
@@ -116,27 +93,27 @@ module ActiveSupport
|
|
116
93
|
def increment(name, amount = 1, **options) # :nodoc:
|
117
94
|
return super unless local_cache
|
118
95
|
value = bypass_local_cache { super }
|
119
|
-
write_cache_value(name, value, **options)
|
96
|
+
write_cache_value(name, value, raw: true, **options)
|
120
97
|
value
|
121
98
|
end
|
122
99
|
|
123
100
|
def decrement(name, amount = 1, **options) # :nodoc:
|
124
101
|
return super unless local_cache
|
125
102
|
value = bypass_local_cache { super }
|
126
|
-
write_cache_value(name, value, **options)
|
103
|
+
write_cache_value(name, value, raw: true, **options)
|
127
104
|
value
|
128
105
|
end
|
129
106
|
|
130
107
|
private
|
131
|
-
def
|
108
|
+
def read_serialized_entry(key, raw: false, **options)
|
132
109
|
if cache = local_cache
|
133
110
|
hit = true
|
134
|
-
|
111
|
+
entry = cache.fetch_entry(key) do
|
135
112
|
hit = false
|
136
113
|
super
|
137
114
|
end
|
138
115
|
options[:event][:store] = cache.class.name if hit && options[:event]
|
139
|
-
|
116
|
+
entry
|
140
117
|
else
|
141
118
|
super
|
142
119
|
end
|
@@ -145,7 +122,10 @@ module ActiveSupport
|
|
145
122
|
def read_multi_entries(keys, **options)
|
146
123
|
return super unless local_cache
|
147
124
|
|
148
|
-
local_entries = local_cache.read_multi_entries(keys
|
125
|
+
local_entries = local_cache.read_multi_entries(keys)
|
126
|
+
local_entries.transform_values! do |payload|
|
127
|
+
deserialize_entry(payload).value
|
128
|
+
end
|
149
129
|
missed_keys = keys - local_entries.keys
|
150
130
|
|
151
131
|
if missed_keys.any?
|
@@ -155,30 +135,27 @@ module ActiveSupport
|
|
155
135
|
end
|
156
136
|
end
|
157
137
|
|
158
|
-
def
|
159
|
-
if
|
160
|
-
local_cache.
|
138
|
+
def write_serialized_entry(key, payload, **)
|
139
|
+
if return_value = super
|
140
|
+
local_cache.write_entry(key, payload) if local_cache
|
161
141
|
else
|
162
|
-
local_cache.
|
142
|
+
local_cache.delete_entry(key) if local_cache
|
163
143
|
end
|
164
|
-
|
165
|
-
super
|
144
|
+
return_value
|
166
145
|
end
|
167
146
|
|
168
|
-
def delete_entry(key, **
|
169
|
-
local_cache.delete_entry(key
|
147
|
+
def delete_entry(key, **)
|
148
|
+
local_cache.delete_entry(key) if local_cache
|
170
149
|
super
|
171
150
|
end
|
172
151
|
|
173
152
|
def write_cache_value(name, value, **options)
|
174
153
|
name = normalize_key(name, options)
|
175
154
|
cache = local_cache
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
cache.delete(name, **options)
|
181
|
-
end
|
155
|
+
if value
|
156
|
+
cache.write_entry(name, serialize_entry(new_entry(value, **options), **options))
|
157
|
+
else
|
158
|
+
cache.delete_entry(name)
|
182
159
|
end
|
183
160
|
end
|
184
161
|
|
@@ -190,8 +167,8 @@ module ActiveSupport
|
|
190
167
|
LocalCacheRegistry.cache_for(local_cache_key)
|
191
168
|
end
|
192
169
|
|
193
|
-
def bypass_local_cache
|
194
|
-
use_temporary_local_cache(nil)
|
170
|
+
def bypass_local_cache(&block)
|
171
|
+
use_temporary_local_cache(nil, &block)
|
195
172
|
end
|
196
173
|
|
197
174
|
def use_temporary_local_cache(temporary_cache)
|