activesupport 5.2.7.1 → 6.1.4.6
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 +399 -434
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +29 -3
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +34 -34
- data/lib/active_support/cache/mem_cache_store.rb +39 -24
- data/lib/active_support/cache/memory_store.rb +59 -33
- data/lib/active_support/cache/null_store.rb +8 -3
- data/lib/active_support/cache/redis_cache_store.rb +72 -45
- data/lib/active_support/cache/strategy/local_cache.rb +41 -26
- data/lib/active_support/cache.rb +148 -78
- data/lib/active_support/callbacks.rb +81 -64
- data/lib/active_support/concern.rb +70 -3
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +0 -1
- data/lib/active_support/configurable.rb +10 -14
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/conversions.rb +5 -5
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/class/attribute.rb +32 -47
- data/lib/active_support/core_ext/class/subclasses.rb +17 -38
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +37 -47
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
- data/lib/active_support/core_ext/enumerable.rb +171 -75
- data/lib/active_support/core_ext/hash/conversions.rb +3 -3
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +2 -2
- data/lib/active_support/core_ext/hash/keys.rb +1 -30
- data/lib/active_support/core_ext/hash/slice.rb +6 -27
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +30 -39
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +17 -19
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +76 -33
- data/lib/active_support/core_ext/module/introspection.rb +16 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/name_error.rb +29 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -129
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +14 -2
- data/lib/active_support/core_ext/object/try.rb +17 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +34 -13
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/each.rb +0 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
- data/lib/active_support/core_ext/regexp.rb +8 -5
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +5 -16
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +45 -6
- data/lib/active_support/core_ext/string/inquiry.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +6 -5
- data/lib/active_support/core_ext/string/output_safety.rb +70 -41
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +51 -3
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +6 -1
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +16 -2
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +109 -34
- data/lib/active_support/deprecation/behaviors.rb +16 -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 +18 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +29 -6
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +6 -1
- data/lib/active_support/descendants_tracker.rb +59 -9
- data/lib/active_support/duration/iso8601_parser.rb +2 -4
- data/lib/active_support/duration/iso8601_serializer.rb +18 -14
- data/lib/active_support/duration.rb +78 -30
- data/lib/active_support/encrypted_configuration.rb +0 -4
- data/lib/active_support/encrypted_file.rb +22 -4
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +82 -117
- data/lib/active_support/execution_wrapper.rb +2 -1
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/fork_tracker.rb +64 -0
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +70 -42
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +15 -8
- data/lib/active_support/inflector/inflections.rb +2 -7
- data/lib/active_support/inflector/methods.rb +49 -58
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +25 -26
- data/lib/active_support/json/encoding.rb +11 -3
- data/lib/active_support/key_generator.rb +1 -33
- data/lib/active_support/lazy_load_hooks.rb +5 -2
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber.rb +39 -9
- data/lib/active_support/logger.rb +2 -17
- data/lib/active_support/logger_silence.rb +11 -19
- data/lib/active_support/logger_thread_safe_level.rb +50 -6
- data/lib/active_support/message_encryptor.rb +8 -13
- data/lib/active_support/message_verifier.rb +10 -10
- data/lib/active_support/messages/metadata.rb +11 -2
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +10 -9
- data/lib/active_support/multibyte/chars.rb +10 -68
- data/lib/active_support/multibyte/unicode.rb +15 -327
- data/lib/active_support/notifications/fanout.rb +116 -16
- data/lib/active_support/notifications/instrumenter.rb +71 -9
- data/lib/active_support/notifications.rb +72 -8
- data/lib/active_support/number_helper/number_converter.rb +5 -6
- data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -7
- data/lib/active_support/number_helper/rounding_helper.rb +12 -28
- data/lib/active_support/number_helper.rb +38 -12
- data/lib/active_support/option_merger.rb +22 -3
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +13 -3
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +1 -1
- data/lib/active_support/rails.rb +1 -10
- data/lib/active_support/railtie.rb +23 -1
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/rescuable.rb +4 -4
- 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 +4 -3
- data/lib/active_support/subscriber.rb +72 -28
- data/lib/active_support/tagged_logging.rb +42 -8
- data/lib/active_support/test_case.rb +91 -0
- data/lib/active_support/testing/assertions.rb +30 -9
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/stream.rb +1 -2
- data/lib/active_support/testing/time_helpers.rb +47 -12
- data/lib/active_support/time_with_zone.rb +81 -47
- data/lib/active_support/values/time_zone.rb +32 -17
- data/lib/active_support/xml_mini/jdom.rb +2 -3
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +10 -3
- data/lib/active_support/xml_mini.rb +2 -10
- data/lib/active_support.rb +14 -1
- metadata +55 -29
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
- data/lib/active_support/core_ext/hash/compact.rb +0 -29
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/core_ext/module/reachable.rb +0 -11
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
- data/lib/active_support/core_ext/range/include_range.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
data/lib/active_support/cache.rb
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
require "zlib"
|
4
4
|
require "active_support/core_ext/array/extract_options"
|
5
5
|
require "active_support/core_ext/array/wrap"
|
6
|
+
require "active_support/core_ext/enumerable"
|
6
7
|
require "active_support/core_ext/module/attribute_accessors"
|
7
8
|
require "active_support/core_ext/numeric/bytes"
|
8
9
|
require "active_support/core_ext/numeric/time"
|
9
10
|
require "active_support/core_ext/object/to_param"
|
11
|
+
require "active_support/core_ext/object/try"
|
10
12
|
require "active_support/core_ext/string/inflections"
|
11
13
|
|
12
14
|
module ActiveSupport
|
@@ -20,7 +22,7 @@ module ActiveSupport
|
|
20
22
|
|
21
23
|
# These options mean something to all cache implementations. Individual cache
|
22
24
|
# implementations may support additional options.
|
23
|
-
UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
|
25
|
+
UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl, :coder]
|
24
26
|
|
25
27
|
module Strategy
|
26
28
|
autoload :LocalCache, "active_support/cache/strategy/local_cache"
|
@@ -52,12 +54,19 @@ module ActiveSupport
|
|
52
54
|
#
|
53
55
|
# ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
|
54
56
|
# # => returns MyOwnCacheStore.new
|
55
|
-
def lookup_store(*
|
56
|
-
store, *parameters = *Array.wrap(store_option).flatten
|
57
|
-
|
57
|
+
def lookup_store(store = nil, *parameters)
|
58
58
|
case store
|
59
59
|
when Symbol
|
60
|
-
|
60
|
+
options = parameters.extract_options!
|
61
|
+
# clean this up once Ruby 2.7 support is dropped
|
62
|
+
# see https://github.com/rails/rails/pull/41522#discussion_r581186602
|
63
|
+
if options.empty?
|
64
|
+
retrieve_store_class(store).new(*parameters)
|
65
|
+
else
|
66
|
+
retrieve_store_class(store).new(*parameters, **options)
|
67
|
+
end
|
68
|
+
when Array
|
69
|
+
lookup_store(*store)
|
61
70
|
when nil
|
62
71
|
ActiveSupport::Cache::MemoryStore.new
|
63
72
|
else
|
@@ -78,7 +87,7 @@ module ActiveSupport
|
|
78
87
|
#
|
79
88
|
# The +key+ argument can also respond to +cache_key+ or +to_param+.
|
80
89
|
def expand_cache_key(key, namespace = nil)
|
81
|
-
expanded_cache_key =
|
90
|
+
expanded_cache_key = namespace ? +"#{namespace}/" : +""
|
82
91
|
|
83
92
|
if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
|
84
93
|
expanded_cache_key << "#{prefix}/"
|
@@ -155,6 +164,8 @@ module ActiveSupport
|
|
155
164
|
# threshold is configurable with the <tt>:compress_threshold</tt> option,
|
156
165
|
# specified in bytes.
|
157
166
|
class Store
|
167
|
+
DEFAULT_CODER = Marshal
|
168
|
+
|
158
169
|
cattr_accessor :logger, instance_writer: true
|
159
170
|
|
160
171
|
attr_reader :silence, :options
|
@@ -182,6 +193,7 @@ module ActiveSupport
|
|
182
193
|
# namespace for the cache.
|
183
194
|
def initialize(options = nil)
|
184
195
|
@options = options ? options.dup : {}
|
196
|
+
@coder = @options.delete(:coder) { self.class::DEFAULT_CODER } || NullCoder
|
185
197
|
end
|
186
198
|
|
187
199
|
# Silences the logger.
|
@@ -229,6 +241,14 @@ module ActiveSupport
|
|
229
241
|
# ask whether you should force a cache write. Otherwise, it's clearer to
|
230
242
|
# just call <tt>Cache#write</tt>.
|
231
243
|
#
|
244
|
+
# Setting <tt>skip_nil: true</tt> will not cache nil result:
|
245
|
+
#
|
246
|
+
# cache.fetch('foo') { nil }
|
247
|
+
# cache.fetch('bar', skip_nil: true) { nil }
|
248
|
+
# cache.exist?('foo') # => true
|
249
|
+
# cache.exist?('bar') # => false
|
250
|
+
#
|
251
|
+
#
|
232
252
|
# Setting <tt>compress: false</tt> disables compression of the cache entry.
|
233
253
|
#
|
234
254
|
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
|
@@ -303,14 +323,14 @@ module ActiveSupport
|
|
303
323
|
# :bar
|
304
324
|
# end
|
305
325
|
# cache.fetch('foo') # => "bar"
|
306
|
-
def fetch(name, options = nil)
|
326
|
+
def fetch(name, options = nil, &block)
|
307
327
|
if block_given?
|
308
328
|
options = merged_options(options)
|
309
329
|
key = normalize_key(name, options)
|
310
330
|
|
311
331
|
entry = nil
|
312
332
|
instrument(:read, name, options) do |payload|
|
313
|
-
cached_entry = read_entry(key, options) unless options[:force]
|
333
|
+
cached_entry = read_entry(key, **options, event: payload) unless options[:force]
|
314
334
|
entry = handle_expired_entry(cached_entry, key, options)
|
315
335
|
entry = nil if entry && entry.mismatched?(normalize_version(name, options))
|
316
336
|
payload[:super_operation] = :fetch if payload
|
@@ -320,7 +340,7 @@ module ActiveSupport
|
|
320
340
|
if entry
|
321
341
|
get_entry_value(entry, name, options)
|
322
342
|
else
|
323
|
-
save_block_result_to_cache(name, options)
|
343
|
+
save_block_result_to_cache(name, options, &block)
|
324
344
|
end
|
325
345
|
elsif options && options[:force]
|
326
346
|
raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block."
|
@@ -333,8 +353,9 @@ module ActiveSupport
|
|
333
353
|
# the cache with the given key, then that data is returned. Otherwise,
|
334
354
|
# +nil+ is returned.
|
335
355
|
#
|
336
|
-
# Note, if data was written with the <tt>:expires_in
|
337
|
-
# both of these conditions are applied before
|
356
|
+
# Note, if data was written with the <tt>:expires_in</tt> or
|
357
|
+
# <tt>:version</tt> options, both of these conditions are applied before
|
358
|
+
# the data is returned.
|
338
359
|
#
|
339
360
|
# Options are passed to the underlying cache implementation.
|
340
361
|
def read(name, options = nil)
|
@@ -343,11 +364,11 @@ module ActiveSupport
|
|
343
364
|
version = normalize_version(name, options)
|
344
365
|
|
345
366
|
instrument(:read, name, options) do |payload|
|
346
|
-
entry = read_entry(key, options)
|
367
|
+
entry = read_entry(key, **options, event: payload)
|
347
368
|
|
348
369
|
if entry
|
349
370
|
if entry.expired?
|
350
|
-
delete_entry(key, options)
|
371
|
+
delete_entry(key, **options)
|
351
372
|
payload[:hit] = false if payload
|
352
373
|
nil
|
353
374
|
elsif entry.mismatched?(version)
|
@@ -375,7 +396,7 @@ module ActiveSupport
|
|
375
396
|
options = merged_options(options)
|
376
397
|
|
377
398
|
instrument :read_multi, names, options do |payload|
|
378
|
-
read_multi_entries(names, options).tap do |results|
|
399
|
+
read_multi_entries(names, **options, event: payload).tap do |results|
|
379
400
|
payload[:hits] = results.keys
|
380
401
|
end
|
381
402
|
end
|
@@ -387,10 +408,10 @@ module ActiveSupport
|
|
387
408
|
|
388
409
|
instrument :write_multi, hash, options do |payload|
|
389
410
|
entries = hash.each_with_object({}) do |(name, value), memo|
|
390
|
-
memo[normalize_key(name, options)] = Entry.new(value, options.merge(version: normalize_version(name, options)))
|
411
|
+
memo[normalize_key(name, options)] = Entry.new(value, **options.merge(version: normalize_version(name, options)))
|
391
412
|
end
|
392
413
|
|
393
|
-
write_multi_entries entries, options
|
414
|
+
write_multi_entries entries, **options
|
394
415
|
end
|
395
416
|
end
|
396
417
|
|
@@ -402,8 +423,6 @@ module ActiveSupport
|
|
402
423
|
# to the cache. If you do not want to write the cache when the cache is
|
403
424
|
# not found, use #read_multi.
|
404
425
|
#
|
405
|
-
# Options are passed to the underlying cache implementation.
|
406
|
-
#
|
407
426
|
# Returns a hash with the data for each of the names. For example:
|
408
427
|
#
|
409
428
|
# cache.write("bim", "bam")
|
@@ -413,6 +432,17 @@ module ActiveSupport
|
|
413
432
|
# # => { "bim" => "bam",
|
414
433
|
# # "unknown_key" => "Fallback value for key: unknown_key" }
|
415
434
|
#
|
435
|
+
# Options are passed to the underlying cache implementation. For example:
|
436
|
+
#
|
437
|
+
# cache.fetch_multi("fizz", expires_in: 5.seconds) do |key|
|
438
|
+
# "buzz"
|
439
|
+
# end
|
440
|
+
# # => {"fizz"=>"buzz"}
|
441
|
+
# cache.read("fizz")
|
442
|
+
# # => "buzz"
|
443
|
+
# sleep(6)
|
444
|
+
# cache.read("fizz")
|
445
|
+
# # => nil
|
416
446
|
def fetch_multi(*names)
|
417
447
|
raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?
|
418
448
|
|
@@ -420,18 +450,18 @@ module ActiveSupport
|
|
420
450
|
options = merged_options(options)
|
421
451
|
|
422
452
|
instrument :read_multi, names, options do |payload|
|
423
|
-
read_multi_entries(names, options)
|
424
|
-
|
425
|
-
|
453
|
+
reads = read_multi_entries(names, **options)
|
454
|
+
writes = {}
|
455
|
+
ordered = names.index_with do |name|
|
456
|
+
reads.fetch(name) { writes[name] = yield(name) }
|
457
|
+
end
|
426
458
|
|
427
|
-
|
459
|
+
payload[:hits] = reads.keys
|
460
|
+
payload[:super_operation] = :fetch_multi
|
428
461
|
|
429
|
-
|
430
|
-
results[name] = writes[name] = yield(name)
|
431
|
-
end
|
462
|
+
write_multi(writes, options)
|
432
463
|
|
433
|
-
|
434
|
-
end
|
464
|
+
ordered
|
435
465
|
end
|
436
466
|
end
|
437
467
|
|
@@ -442,8 +472,8 @@ module ActiveSupport
|
|
442
472
|
options = merged_options(options)
|
443
473
|
|
444
474
|
instrument(:write, name, options) do
|
445
|
-
entry = Entry.new(value, options.merge(version: normalize_version(name, options)))
|
446
|
-
write_entry(normalize_key(name, options), entry, options)
|
475
|
+
entry = Entry.new(value, **options.merge(version: normalize_version(name, options)))
|
476
|
+
write_entry(normalize_key(name, options), entry, **options)
|
447
477
|
end
|
448
478
|
end
|
449
479
|
|
@@ -454,7 +484,19 @@ module ActiveSupport
|
|
454
484
|
options = merged_options(options)
|
455
485
|
|
456
486
|
instrument(:delete, name) do
|
457
|
-
delete_entry(normalize_key(name, options), options)
|
487
|
+
delete_entry(normalize_key(name, options), **options)
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
# Deletes multiple entries in the cache.
|
492
|
+
#
|
493
|
+
# Options are passed to the underlying cache implementation.
|
494
|
+
def delete_multi(names, options = nil)
|
495
|
+
options = merged_options(options)
|
496
|
+
names.map! { |key| normalize_key(key, options) }
|
497
|
+
|
498
|
+
instrument :delete_multi, names do
|
499
|
+
delete_multi_entries(names, **options)
|
458
500
|
end
|
459
501
|
end
|
460
502
|
|
@@ -464,8 +506,8 @@ module ActiveSupport
|
|
464
506
|
def exist?(name, options = nil)
|
465
507
|
options = merged_options(options)
|
466
508
|
|
467
|
-
instrument(:exist?, name) do
|
468
|
-
entry = read_entry(normalize_key(name, options), options)
|
509
|
+
instrument(:exist?, name) do |payload|
|
510
|
+
entry = read_entry(normalize_key(name, options), **options, event: payload)
|
469
511
|
(entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false
|
470
512
|
end
|
471
513
|
end
|
@@ -474,7 +516,7 @@ module ActiveSupport
|
|
474
516
|
#
|
475
517
|
# Options are passed to the underlying cache implementation.
|
476
518
|
#
|
477
|
-
#
|
519
|
+
# Some implementations may not support this method.
|
478
520
|
def delete_matched(matcher, options = nil)
|
479
521
|
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
|
480
522
|
end
|
@@ -483,7 +525,7 @@ module ActiveSupport
|
|
483
525
|
#
|
484
526
|
# Options are passed to the underlying cache implementation.
|
485
527
|
#
|
486
|
-
#
|
528
|
+
# Some implementations may not support this method.
|
487
529
|
def increment(name, amount = 1, options = nil)
|
488
530
|
raise NotImplementedError.new("#{self.class.name} does not support increment")
|
489
531
|
end
|
@@ -492,7 +534,7 @@ module ActiveSupport
|
|
492
534
|
#
|
493
535
|
# Options are passed to the underlying cache implementation.
|
494
536
|
#
|
495
|
-
#
|
537
|
+
# Some implementations may not support this method.
|
496
538
|
def decrement(name, amount = 1, options = nil)
|
497
539
|
raise NotImplementedError.new("#{self.class.name} does not support decrement")
|
498
540
|
end
|
@@ -501,7 +543,7 @@ module ActiveSupport
|
|
501
543
|
#
|
502
544
|
# Options are passed to the underlying cache implementation.
|
503
545
|
#
|
504
|
-
#
|
546
|
+
# Some implementations may not support this method.
|
505
547
|
def cleanup(options = nil)
|
506
548
|
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
|
507
549
|
end
|
@@ -511,7 +553,7 @@ module ActiveSupport
|
|
511
553
|
#
|
512
554
|
# The options hash is passed to the underlying cache implementation.
|
513
555
|
#
|
514
|
-
#
|
556
|
+
# Some implementations may not support this method.
|
515
557
|
def clear(options = nil)
|
516
558
|
raise NotImplementedError.new("#{self.class.name} does not support clear")
|
517
559
|
end
|
@@ -538,58 +580,73 @@ module ActiveSupport
|
|
538
580
|
|
539
581
|
# Reads an entry from the cache implementation. Subclasses must implement
|
540
582
|
# this method.
|
541
|
-
def read_entry(key, options)
|
583
|
+
def read_entry(key, **options)
|
542
584
|
raise NotImplementedError.new
|
543
585
|
end
|
544
586
|
|
545
587
|
# Writes an entry to the cache implementation. Subclasses must implement
|
546
588
|
# this method.
|
547
|
-
def write_entry(key, entry, options)
|
589
|
+
def write_entry(key, entry, **options)
|
548
590
|
raise NotImplementedError.new
|
549
591
|
end
|
550
592
|
|
593
|
+
def serialize_entry(entry)
|
594
|
+
@coder.dump(entry)
|
595
|
+
end
|
596
|
+
|
597
|
+
def deserialize_entry(payload)
|
598
|
+
payload.nil? ? nil : @coder.load(payload)
|
599
|
+
end
|
600
|
+
|
551
601
|
# Reads multiple entries from the cache implementation. Subclasses MAY
|
552
602
|
# implement this method.
|
553
|
-
def read_multi_entries(names, options)
|
554
|
-
|
555
|
-
|
556
|
-
|
603
|
+
def read_multi_entries(names, **options)
|
604
|
+
names.each_with_object({}) do |name, results|
|
605
|
+
key = normalize_key(name, options)
|
606
|
+
entry = read_entry(key, **options)
|
607
|
+
|
608
|
+
next unless entry
|
609
|
+
|
557
610
|
version = normalize_version(name, options)
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
elsif entry.mismatched?(version)
|
564
|
-
# Skip mismatched versions
|
565
|
-
else
|
566
|
-
results[name] = entry.value
|
567
|
-
end
|
611
|
+
|
612
|
+
if entry.expired?
|
613
|
+
delete_entry(key, **options)
|
614
|
+
elsif !entry.mismatched?(version)
|
615
|
+
results[name] = entry.value
|
568
616
|
end
|
569
617
|
end
|
570
|
-
results
|
571
618
|
end
|
572
619
|
|
573
620
|
# Writes multiple entries to the cache implementation. Subclasses MAY
|
574
621
|
# implement this method.
|
575
|
-
def write_multi_entries(hash, options)
|
622
|
+
def write_multi_entries(hash, **options)
|
576
623
|
hash.each do |key, entry|
|
577
|
-
write_entry key, entry, options
|
624
|
+
write_entry key, entry, **options
|
578
625
|
end
|
579
626
|
end
|
580
627
|
|
581
628
|
# Deletes an entry from the cache implementation. Subclasses must
|
582
629
|
# implement this method.
|
583
|
-
def delete_entry(key, options)
|
630
|
+
def delete_entry(key, **options)
|
584
631
|
raise NotImplementedError.new
|
585
632
|
end
|
586
633
|
|
634
|
+
# Deletes multiples entries in the cache implementation. Subclasses MAY
|
635
|
+
# implement this method.
|
636
|
+
def delete_multi_entries(entries, **options)
|
637
|
+
entries.count { |key| delete_entry(key, **options) }
|
638
|
+
end
|
639
|
+
|
587
640
|
# Merges the default options with ones specific to a method call.
|
588
641
|
def merged_options(call_options)
|
589
642
|
if call_options
|
590
|
-
options.
|
643
|
+
if options.empty?
|
644
|
+
call_options
|
645
|
+
else
|
646
|
+
options.merge(call_options)
|
647
|
+
end
|
591
648
|
else
|
592
|
-
options
|
649
|
+
options
|
593
650
|
end
|
594
651
|
end
|
595
652
|
|
@@ -616,6 +673,10 @@ module ActiveSupport
|
|
616
673
|
namespace = namespace.call
|
617
674
|
end
|
618
675
|
|
676
|
+
if key && key.encoding != Encoding::UTF_8
|
677
|
+
key = key.dup.force_encoding(Encoding::UTF_8)
|
678
|
+
end
|
679
|
+
|
619
680
|
if namespace
|
620
681
|
"#{namespace}:#{key}"
|
621
682
|
else
|
@@ -632,15 +693,15 @@ module ActiveSupport
|
|
632
693
|
case key
|
633
694
|
when Array
|
634
695
|
if key.size > 1
|
635
|
-
key
|
696
|
+
key.collect { |element| expanded_key(element) }
|
636
697
|
else
|
637
|
-
key
|
698
|
+
expanded_key(key.first)
|
638
699
|
end
|
639
700
|
when Hash
|
640
|
-
key
|
641
|
-
|
642
|
-
|
643
|
-
|
701
|
+
key.collect { |k, v| "#{k}=#{v}" }.sort!
|
702
|
+
else
|
703
|
+
key
|
704
|
+
end.to_param
|
644
705
|
end
|
645
706
|
|
646
707
|
def normalize_version(key, options = nil)
|
@@ -650,24 +711,21 @@ module ActiveSupport
|
|
650
711
|
def expanded_version(key)
|
651
712
|
case
|
652
713
|
when key.respond_to?(:cache_version) then key.cache_version.to_param
|
653
|
-
when key.is_a?(Array) then key.map { |element| expanded_version(element) }.compact.to_param
|
714
|
+
when key.is_a?(Array) then key.map { |element| expanded_version(element) }.tap(&:compact!).to_param
|
654
715
|
when key.respond_to?(:to_a) then expanded_version(key.to_a)
|
655
716
|
end
|
656
717
|
end
|
657
718
|
|
658
719
|
def instrument(operation, key, options = nil)
|
659
|
-
|
720
|
+
if logger && logger.debug? && !silence?
|
721
|
+
logger.debug "Cache #{operation}: #{normalize_key(key, options)}#{options.blank? ? "" : " (#{options.inspect})"}"
|
722
|
+
end
|
660
723
|
|
661
|
-
payload = { key: key }
|
724
|
+
payload = { key: key, store: self.class.name }
|
662
725
|
payload.merge!(options) if options.is_a?(Hash)
|
663
726
|
ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload) { yield(payload) }
|
664
727
|
end
|
665
728
|
|
666
|
-
def log
|
667
|
-
return unless logger && logger.debug? && !silence?
|
668
|
-
logger.debug(yield)
|
669
|
-
end
|
670
|
-
|
671
729
|
def handle_expired_entry(entry, key, options)
|
672
730
|
if entry && entry.expired?
|
673
731
|
race_ttl = options[:race_condition_ttl].to_i
|
@@ -677,7 +735,7 @@ module ActiveSupport
|
|
677
735
|
entry.expires_at = Time.now + race_ttl
|
678
736
|
write_entry(key, entry, expires_in: race_ttl * 2)
|
679
737
|
else
|
680
|
-
delete_entry(key, options)
|
738
|
+
delete_entry(key, **options)
|
681
739
|
end
|
682
740
|
entry = nil
|
683
741
|
end
|
@@ -685,7 +743,7 @@ module ActiveSupport
|
|
685
743
|
end
|
686
744
|
|
687
745
|
def get_entry_value(entry, name, options)
|
688
|
-
instrument(:fetch_hit, name, options) {}
|
746
|
+
instrument(:fetch_hit, name, options) { }
|
689
747
|
entry.value
|
690
748
|
end
|
691
749
|
|
@@ -694,11 +752,23 @@ module ActiveSupport
|
|
694
752
|
yield(name)
|
695
753
|
end
|
696
754
|
|
697
|
-
write(name, result, options)
|
755
|
+
write(name, result, options) unless result.nil? && options[:skip_nil]
|
698
756
|
result
|
699
757
|
end
|
700
758
|
end
|
701
759
|
|
760
|
+
module NullCoder # :nodoc:
|
761
|
+
class << self
|
762
|
+
def load(payload)
|
763
|
+
payload
|
764
|
+
end
|
765
|
+
|
766
|
+
def dump(entry)
|
767
|
+
entry
|
768
|
+
end
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
702
772
|
# This class is used to represent cache entries. Cache entries have a value, an optional
|
703
773
|
# expiration time, and an optional version. The expiration time is used to support the :race_condition_ttl option
|
704
774
|
# on the cache. The version is used to support the :version option on the cache for rejecting
|
@@ -749,8 +819,8 @@ module ActiveSupport
|
|
749
819
|
end
|
750
820
|
|
751
821
|
# Returns the size of the cached value. This could be less than
|
752
|
-
# <tt>value.
|
753
|
-
def
|
822
|
+
# <tt>value.bytesize</tt> if the data is compressed.
|
823
|
+
def bytesize
|
754
824
|
case value
|
755
825
|
when NilClass
|
756
826
|
0
|