activesupport 7.1.3.4 → 8.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -1136
  3. data/lib/active_support/array_inquirer.rb +1 -1
  4. data/lib/active_support/backtrace_cleaner.rb +15 -3
  5. data/lib/active_support/benchmark.rb +21 -0
  6. data/lib/active_support/benchmarkable.rb +3 -2
  7. data/lib/active_support/broadcast_logger.rb +19 -18
  8. data/lib/active_support/cache/file_store.rb +27 -12
  9. data/lib/active_support/cache/mem_cache_store.rb +16 -74
  10. data/lib/active_support/cache/memory_store.rb +8 -3
  11. data/lib/active_support/cache/redis_cache_store.rb +21 -15
  12. data/lib/active_support/cache/serializer_with_fallback.rb +0 -23
  13. data/lib/active_support/cache.rb +76 -78
  14. data/lib/active_support/callbacks.rb +79 -116
  15. data/lib/active_support/class_attribute.rb +33 -0
  16. data/lib/active_support/code_generator.rb +24 -10
  17. data/lib/active_support/concurrency/share_lock.rb +0 -1
  18. data/lib/active_support/configuration_file.rb +15 -6
  19. data/lib/active_support/core_ext/array/conversions.rb +3 -5
  20. data/lib/active_support/core_ext/benchmark.rb +6 -9
  21. data/lib/active_support/core_ext/class/attribute.rb +24 -20
  22. data/lib/active_support/core_ext/class/subclasses.rb +15 -35
  23. data/lib/active_support/core_ext/date/blank.rb +4 -0
  24. data/lib/active_support/core_ext/date/conversions.rb +2 -2
  25. data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
  26. data/lib/active_support/core_ext/date_time/blank.rb +4 -0
  27. data/lib/active_support/core_ext/date_time/conversions.rb +0 -4
  28. data/lib/active_support/core_ext/digest/uuid.rb +6 -0
  29. data/lib/active_support/core_ext/enumerable.rb +8 -3
  30. data/lib/active_support/core_ext/erb/util.rb +7 -2
  31. data/lib/active_support/core_ext/hash/except.rb +0 -12
  32. data/lib/active_support/core_ext/hash/keys.rb +4 -4
  33. data/lib/active_support/core_ext/module/attr_internal.rb +16 -6
  34. data/lib/active_support/core_ext/module/delegation.rb +20 -148
  35. data/lib/active_support/core_ext/module/deprecation.rb +1 -4
  36. data/lib/active_support/core_ext/numeric/conversions.rb +3 -3
  37. data/lib/active_support/core_ext/object/blank.rb +45 -1
  38. data/lib/active_support/core_ext/object/duplicable.rb +24 -15
  39. data/lib/active_support/core_ext/object/instance_variables.rb +11 -19
  40. data/lib/active_support/core_ext/object/json.rb +21 -13
  41. data/lib/active_support/core_ext/object/with.rb +5 -3
  42. data/lib/active_support/core_ext/pathname/blank.rb +4 -0
  43. data/lib/active_support/core_ext/range/overlap.rb +1 -1
  44. data/lib/active_support/core_ext/securerandom.rb +4 -4
  45. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  46. data/lib/active_support/core_ext/string/filters.rb +1 -1
  47. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  48. data/lib/active_support/core_ext/string/output_safety.rb +0 -7
  49. data/lib/active_support/core_ext/thread/backtrace/location.rb +2 -7
  50. data/lib/active_support/core_ext/time/calculations.rb +32 -30
  51. data/lib/active_support/core_ext/time/compatibility.rb +24 -0
  52. data/lib/active_support/core_ext/time/conversions.rb +2 -2
  53. data/lib/active_support/core_ext/time/zones.rb +1 -1
  54. data/lib/active_support/core_ext.rb +0 -1
  55. data/lib/active_support/current_attributes.rb +38 -40
  56. data/lib/active_support/delegation.rb +200 -0
  57. data/lib/active_support/dependencies/autoload.rb +0 -12
  58. data/lib/active_support/dependencies.rb +0 -1
  59. data/lib/active_support/deprecation/constant_accessor.rb +47 -26
  60. data/lib/active_support/deprecation/proxy_wrappers.rb +9 -12
  61. data/lib/active_support/deprecation/reporting.rb +3 -17
  62. data/lib/active_support/deprecation.rb +8 -5
  63. data/lib/active_support/descendants_tracker.rb +9 -87
  64. data/lib/active_support/duration/iso8601_parser.rb +2 -2
  65. data/lib/active_support/duration/iso8601_serializer.rb +1 -2
  66. data/lib/active_support/duration.rb +25 -16
  67. data/lib/active_support/encrypted_configuration.rb +20 -2
  68. data/lib/active_support/encrypted_file.rb +1 -1
  69. data/lib/active_support/error_reporter.rb +65 -3
  70. data/lib/active_support/evented_file_update_checker.rb +0 -2
  71. data/lib/active_support/execution_wrapper.rb +0 -1
  72. data/lib/active_support/file_update_checker.rb +1 -1
  73. data/lib/active_support/fork_tracker.rb +2 -38
  74. data/lib/active_support/gem_version.rb +4 -4
  75. data/lib/active_support/hash_with_indifferent_access.rb +21 -23
  76. data/lib/active_support/html_safe_translation.rb +7 -4
  77. data/lib/active_support/i18n_railtie.rb +19 -11
  78. data/lib/active_support/isolated_execution_state.rb +0 -2
  79. data/lib/active_support/json/encoding.rb +3 -3
  80. data/lib/active_support/log_subscriber.rb +1 -12
  81. data/lib/active_support/logger.rb +15 -2
  82. data/lib/active_support/logger_thread_safe_level.rb +0 -8
  83. data/lib/active_support/message_pack/extensions.rb +15 -2
  84. data/lib/active_support/message_verifier.rb +12 -0
  85. data/lib/active_support/messages/codec.rb +1 -1
  86. data/lib/active_support/multibyte/chars.rb +2 -2
  87. data/lib/active_support/notifications/fanout.rb +4 -8
  88. data/lib/active_support/notifications/instrumenter.rb +32 -21
  89. data/lib/active_support/notifications.rb +28 -27
  90. data/lib/active_support/number_helper/number_converter.rb +2 -2
  91. data/lib/active_support/number_helper.rb +22 -0
  92. data/lib/active_support/option_merger.rb +2 -2
  93. data/lib/active_support/ordered_options.rb +53 -15
  94. data/lib/active_support/railtie.rb +8 -11
  95. data/lib/active_support/string_inquirer.rb +1 -1
  96. data/lib/active_support/subscriber.rb +1 -0
  97. data/lib/active_support/syntax_error_proxy.rb +1 -11
  98. data/lib/active_support/tagged_logging.rb +9 -1
  99. data/lib/active_support/test_case.rb +3 -1
  100. data/lib/active_support/testing/assertions.rb +79 -21
  101. data/lib/active_support/testing/constant_stubbing.rb +30 -8
  102. data/lib/active_support/testing/deprecation.rb +5 -12
  103. data/lib/active_support/testing/isolation.rb +19 -9
  104. data/lib/active_support/testing/method_call_assertions.rb +2 -16
  105. data/lib/active_support/testing/parallelization/server.rb +3 -0
  106. data/lib/active_support/testing/setup_and_teardown.rb +2 -0
  107. data/lib/active_support/testing/strict_warnings.rb +8 -4
  108. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  109. data/lib/active_support/testing/time_helpers.rb +4 -3
  110. data/lib/active_support/time_with_zone.rb +30 -17
  111. data/lib/active_support/values/time_zone.rb +25 -14
  112. data/lib/active_support/xml_mini.rb +11 -2
  113. data/lib/active_support.rb +12 -4
  114. metadata +68 -19
  115. data/lib/active_support/deprecation/instance_delegator.rb +0 -65
  116. data/lib/active_support/proxy_object.rb +0 -17
  117. data/lib/active_support/ruby_features.rb +0 -7
@@ -39,7 +39,7 @@ module ActiveSupport
39
39
  name.end_with?("?") || super
40
40
  end
41
41
 
42
- def method_missing(name, *args)
42
+ def method_missing(name, ...)
43
43
  if name.end_with?("?")
44
44
  any?(name[0..-2])
45
45
  else
@@ -17,7 +17,8 @@ module ActiveSupport
17
17
  # can focus on the rest.
18
18
  #
19
19
  # bc = ActiveSupport::BacktraceCleaner.new
20
- # bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
20
+ # root = "#{Rails.root}/"
21
+ # bc.add_filter { |line| line.delete_prefix(root) } # strip the Rails.root prefix
21
22
  # bc.add_silencer { |line| /puma|rubygems/.match?(line) } # skip any lines from puma or rubygems
22
23
  # bc.clean(exception.backtrace) # perform the cleanup
23
24
  #
@@ -33,6 +34,7 @@ module ActiveSupport
33
34
  class BacktraceCleaner
34
35
  def initialize
35
36
  @filters, @silencers = [], []
37
+ add_core_silencer
36
38
  add_gem_filter
37
39
  add_gem_silencer
38
40
  add_stdlib_silencer
@@ -75,8 +77,9 @@ module ActiveSupport
75
77
  # Adds a filter from the block provided. Each line in the backtrace will be
76
78
  # mapped against this filter.
77
79
  #
78
- # # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
79
- # backtrace_cleaner.add_filter { |line| line.gsub(Rails.root.to_s, '') }
80
+ # # Will turn "/my/rails/root/app/models/person.rb" into "app/models/person.rb"
81
+ # root = "#{Rails.root}/"
82
+ # backtrace_cleaner.add_filter { |line| line.start_with?(root) ? line.from(root.size) : line }
80
83
  def add_filter(&block)
81
84
  @filters << block
82
85
  end
@@ -107,6 +110,11 @@ module ActiveSupport
107
110
  private
108
111
  FORMATTED_GEMS_PATTERN = /\A[^\/]+ \([\w.]+\) /
109
112
 
113
+ def initialize_copy(_other)
114
+ @filters = @filters.dup
115
+ @silencers = @silencers.dup
116
+ end
117
+
110
118
  def add_gem_filter
111
119
  gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
112
120
  return if gems_paths.empty?
@@ -116,6 +124,10 @@ module ActiveSupport
116
124
  add_filter { |line| line.sub(gems_regexp, gems_result) }
117
125
  end
118
126
 
127
+ def add_core_silencer
128
+ add_silencer { |line| line.include?("<internal:") }
129
+ end
130
+
119
131
  def add_gem_silencer
120
132
  add_silencer { |line| FORMATTED_GEMS_PATTERN.match?(line) }
121
133
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Benchmark # :nodoc:
5
+ # Benchmark realtime in the specified time unit. By default,
6
+ # the returned unit is in seconds.
7
+ #
8
+ # ActiveSupport::Benchmark.realtime { sleep 0.1 }
9
+ # # => 0.10007
10
+ #
11
+ # ActiveSupport::Benchmark.realtime(:float_millisecond) { sleep 0.1 }
12
+ # # => 100.07
13
+ #
14
+ # `unit` can be any of the values accepted by Ruby's `Process.clock_gettime`.
15
+ def self.realtime(unit = :float_second, &block)
16
+ time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC, unit)
17
+ yield
18
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, unit) - time_start
19
+ end
20
+ end
21
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/benchmark"
4
3
  require "active_support/core_ext/hash/keys"
5
4
 
6
5
  module ActiveSupport
@@ -41,7 +40,9 @@ module ActiveSupport
41
40
  options[:level] ||= :info
42
41
 
43
42
  result = nil
44
- ms = Benchmark.ms { result = options[:silence] ? logger.silence(&block) : yield }
43
+ ms = ActiveSupport::Benchmark.realtime(:float_millisecond) do
44
+ result = options[:silence] ? logger.silence(&block) : yield
45
+ end
45
46
  logger.public_send(options[:level], "%s (%.1fms)" % [ message, ms ])
46
47
  result
47
48
  else
@@ -113,33 +113,33 @@ module ActiveSupport
113
113
  dispatch { |logger| logger.<<(message) }
114
114
  end
115
115
 
116
- def add(*args, &block)
117
- dispatch { |logger| logger.add(*args, &block) }
116
+ def add(...)
117
+ dispatch { |logger| logger.add(...) }
118
118
  end
119
119
  alias_method :log, :add
120
120
 
121
- def debug(*args, &block)
122
- dispatch { |logger| logger.debug(*args, &block) }
121
+ def debug(...)
122
+ dispatch { |logger| logger.debug(...) }
123
123
  end
124
124
 
125
- def info(*args, &block)
126
- dispatch { |logger| logger.info(*args, &block) }
125
+ def info(...)
126
+ dispatch { |logger| logger.info(...) }
127
127
  end
128
128
 
129
- def warn(*args, &block)
130
- dispatch { |logger| logger.warn(*args, &block) }
129
+ def warn(...)
130
+ dispatch { |logger| logger.warn(...) }
131
131
  end
132
132
 
133
- def error(*args, &block)
134
- dispatch { |logger| logger.error(*args, &block) }
133
+ def error(...)
134
+ dispatch { |logger| logger.error(...) }
135
135
  end
136
136
 
137
- def fatal(*args, &block)
138
- dispatch { |logger| logger.fatal(*args, &block) }
137
+ def fatal(...)
138
+ dispatch { |logger| logger.fatal(...) }
139
139
  end
140
140
 
141
- def unknown(*args, &block)
142
- dispatch { |logger| logger.unknown(*args, &block) }
141
+ def unknown(...)
142
+ dispatch { |logger| logger.unknown(...) }
143
143
  end
144
144
 
145
145
  def formatter=(formatter)
@@ -229,17 +229,18 @@ module ActiveSupport
229
229
  private
230
230
  def dispatch(&block)
231
231
  @broadcasts.each { |logger| block.call(logger) }
232
+ true
232
233
  end
233
234
 
234
- def method_missing(name, *args, **kwargs, &block)
235
+ def method_missing(name, ...)
235
236
  loggers = @broadcasts.select { |logger| logger.respond_to?(name) }
236
237
 
237
238
  if loggers.none?
238
- super(name, *args, **kwargs, &block)
239
+ super
239
240
  elsif loggers.one?
240
- loggers.first.send(name, *args, **kwargs, &block)
241
+ loggers.first.send(name, ...)
241
242
  else
242
- loggers.map { |logger| logger.send(name, *args, **kwargs, &block) }
243
+ loggers.map { |logger| logger.send(name, ...) }
243
244
  end
244
245
  end
245
246
 
@@ -58,7 +58,12 @@ module ActiveSupport
58
58
  # cache.increment("baz") # => 6
59
59
  #
60
60
  def increment(name, amount = 1, options = nil)
61
- modify_value(name, amount, options)
61
+ options = merged_options(options)
62
+ key = normalize_key(name, options)
63
+
64
+ instrument(:increment, key, amount: amount) do
65
+ modify_value(name, amount, options)
66
+ end
62
67
  end
63
68
 
64
69
  # Decrement a cached integer value. Returns the updated value.
@@ -73,13 +78,19 @@ module ActiveSupport
73
78
  # cache.decrement("baz") # => 4
74
79
  #
75
80
  def decrement(name, amount = 1, options = nil)
76
- modify_value(name, -amount, options)
81
+ options = merged_options(options)
82
+ key = normalize_key(name, options)
83
+
84
+ instrument(:decrement, key, amount: amount) do
85
+ modify_value(name, -amount, options)
86
+ end
77
87
  end
78
88
 
79
89
  def delete_matched(matcher, options = nil)
80
90
  options = merged_options(options)
91
+ matcher = key_matcher(matcher, options)
92
+
81
93
  instrument(:delete_matched, matcher.inspect) do
82
- matcher = key_matcher(matcher, options)
83
94
  search_dir(cache_path) do |path|
84
95
  key = file_path_key(path)
85
96
  delete_entry(path, **options) if key.match(matcher)
@@ -209,18 +220,22 @@ module ActiveSupport
209
220
  # Modifies the amount of an integer value that is stored in the cache.
210
221
  # If the key is not found it is created and set to +amount+.
211
222
  def modify_value(name, amount, options)
212
- file_name = normalize_key(name, options)
223
+ options = merged_options(options)
224
+ key = normalize_key(name, options)
225
+ version = normalize_version(name, options)
226
+ amount = Integer(amount)
213
227
 
214
- lock_file(file_name) do
215
- options = merged_options(options)
228
+ lock_file(key) do
229
+ entry = read_entry(key, **options)
216
230
 
217
- if num = read(name, options)
218
- num = num.to_i + amount
219
- write(name, num, options)
220
- num
221
- else
222
- write(name, Integer(amount), options)
231
+ if !entry || entry.expired? || entry.mismatched?(version)
232
+ write(name, amount, options)
223
233
  amount
234
+ else
235
+ num = entry.value.to_i + amount
236
+ entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version)
237
+ write_entry(key, entry)
238
+ num
224
239
  end
225
240
  end
226
241
  end
@@ -41,46 +41,6 @@ module ActiveSupport
41
41
 
42
42
  prepend Strategy::LocalCache
43
43
 
44
- module DupLocalCache
45
- class DupLocalStore < DelegateClass(Strategy::LocalCache::LocalStore)
46
- def write_entry(_key, entry)
47
- if entry.is_a?(Entry)
48
- entry.dup_value!
49
- end
50
- super
51
- end
52
-
53
- def fetch_entry(key)
54
- entry = super do
55
- new_entry = yield
56
- if entry.is_a?(Entry)
57
- new_entry.dup_value!
58
- end
59
- new_entry
60
- end
61
- entry = entry.dup
62
-
63
- if entry.is_a?(Entry)
64
- entry.dup_value!
65
- end
66
-
67
- entry
68
- end
69
- end
70
-
71
- private
72
- def local_cache
73
- if ActiveSupport::Cache.format_version == 6.1
74
- if local_cache = super
75
- DupLocalStore.new(local_cache)
76
- end
77
- else
78
- super
79
- end
80
- end
81
- end
82
- prepend DupLocalCache
83
-
84
44
  KEY_MAX_SIZE = 250
85
45
  ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
86
46
 
@@ -114,7 +74,6 @@ module ActiveSupport
114
74
  #
115
75
  # If no addresses are provided, but <tt>ENV['MEMCACHE_SERVERS']</tt> is defined, it will be used instead. Otherwise,
116
76
  # +MemCacheStore+ will connect to localhost:11211 (the default memcached port).
117
- # Passing a +Dalli::Client+ instance is deprecated and will be removed. Please pass an address instead.
118
77
  def initialize(*addresses)
119
78
  addresses = addresses.flatten
120
79
  options = addresses.extract_options!
@@ -126,19 +85,12 @@ module ActiveSupport
126
85
  unless [String, Dalli::Client, NilClass].include?(addresses.first.class)
127
86
  raise ArgumentError, "First argument must be an empty array, address, or array of addresses."
128
87
  end
129
- if addresses.first.is_a?(Dalli::Client)
130
- ActiveSupport.deprecator.warn(<<~MSG)
131
- Initializing MemCacheStore with a Dalli::Client is deprecated and will be removed in Rails 7.2.
132
- Use memcached server addresses instead.
133
- MSG
134
- @data = addresses.first
135
- else
136
- @mem_cache_options = options.dup
137
- # The value "compress: false" prevents duplicate compression within Dalli.
138
- @mem_cache_options[:compress] = false
139
- (OVERRIDDEN_OPTIONS - %i(compress)).each { |name| @mem_cache_options.delete(name) }
140
- @data = self.class.build_mem_cache(*(addresses + [@mem_cache_options]))
141
- end
88
+
89
+ @mem_cache_options = options.dup
90
+ # The value "compress: false" prevents duplicate compression within Dalli.
91
+ @mem_cache_options[:compress] = false
92
+ (OVERRIDDEN_OPTIONS - %i(compress)).each { |name| @mem_cache_options.delete(name) }
93
+ @data = self.class.build_mem_cache(*(addresses + [@mem_cache_options]))
142
94
  end
143
95
 
144
96
  def inspect
@@ -179,9 +131,11 @@ module ActiveSupport
179
131
  # <tt>raw: true</tt>, will fail and return +nil+.
180
132
  def increment(name, amount = 1, options = nil)
181
133
  options = merged_options(options)
182
- instrument(:increment, name, amount: amount) do
134
+ key = normalize_key(name, options)
135
+
136
+ instrument(:increment, key, amount: amount) do
183
137
  rescue_error_with nil do
184
- @data.with { |c| c.incr(normalize_key(name, options), amount, options[:expires_in], amount) }
138
+ @data.with { |c| c.incr(key, amount, options[:expires_in], amount) }
185
139
  end
186
140
  end
187
141
  end
@@ -203,9 +157,11 @@ module ActiveSupport
203
157
  # <tt>raw: true</tt>, will fail and return +nil+.
204
158
  def decrement(name, amount = 1, options = nil)
205
159
  options = merged_options(options)
206
- instrument(:decrement, name, amount: amount) do
160
+ key = normalize_key(name, options)
161
+
162
+ instrument(:decrement, key, amount: amount) do
207
163
  rescue_error_with nil do
208
- @data.with { |c| c.decr(normalize_key(name, options), amount, options[:expires_in], 0) }
164
+ @data.with { |c| c.decr(key, amount, options[:expires_in], 0) }
209
165
  end
210
166
  end
211
167
  end
@@ -222,20 +178,6 @@ module ActiveSupport
222
178
  end
223
179
 
224
180
  private
225
- def default_serializer
226
- if Cache.format_version == 6.1
227
- ActiveSupport.deprecator.warn <<~EOM
228
- Support for `config.active_support.cache_format_version = 6.1` has been deprecated and will be removed in Rails 7.2.
229
-
230
- Check the Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
231
- for more information on how to upgrade.
232
- EOM
233
- Cache::SerializerWithFallback[:passthrough]
234
- else
235
- super
236
- end
237
- end
238
-
239
181
  # Read an entry from the cache.
240
182
  def read_entry(key, **options)
241
183
  deserialize_entry(read_serialized_entry(key, **options), **options)
@@ -259,10 +201,10 @@ module ActiveSupport
259
201
  # Set the memcache expire a few minutes in the future to support race condition ttls on read
260
202
  expires_in += 5.minutes
261
203
  end
262
- rescue_error_with false do
204
+ rescue_error_with nil do
263
205
  # Don't pass compress option to Dalli since we are already dealing with compression.
264
206
  options.delete(:compress)
265
- @data.with { |c| c.send(method, key, payload, expires_in, **options) }
207
+ @data.with { |c| !!c.send(method, key, payload, expires_in, **options) }
266
208
  end
267
209
  end
268
210
 
@@ -147,7 +147,9 @@ module ActiveSupport
147
147
  # cache.increment("baz") # => 6
148
148
  #
149
149
  def increment(name, amount = 1, options = nil)
150
- modify_value(name, amount, options)
150
+ instrument(:increment, name, amount: amount) do
151
+ modify_value(name, amount, options)
152
+ end
151
153
  end
152
154
 
153
155
  # Decrement a cached integer value. Returns the updated value.
@@ -162,14 +164,17 @@ module ActiveSupport
162
164
  # cache.decrement("baz") # => 4
163
165
  #
164
166
  def decrement(name, amount = 1, options = nil)
165
- modify_value(name, -amount, options)
167
+ instrument(:decrement, name, amount: amount) do
168
+ modify_value(name, -amount, options)
169
+ end
166
170
  end
167
171
 
168
172
  # Deletes cache entries if the cache key matches a given pattern.
169
173
  def delete_matched(matcher, options = nil)
170
174
  options = merged_options(options)
175
+ matcher = key_matcher(matcher, options)
176
+
171
177
  instrument(:delete_matched, matcher.inspect) do
172
- matcher = key_matcher(matcher, options)
173
178
  keys = synchronize { @data.keys }
174
179
  keys.each do |key|
175
180
  delete_entry(key, **options) if key.match(matcher)
@@ -173,9 +173,12 @@ module ActiveSupport
173
173
  return {} if names.empty?
174
174
 
175
175
  options = names.extract_options!
176
- instrument_multi(:read_multi, names, options) do |payload|
176
+ options = merged_options(options)
177
+ keys = names.map { |name| normalize_key(name, options) }
178
+
179
+ instrument_multi(:read_multi, keys, options) do |payload|
177
180
  read_multi_entries(names, **options).tap do |results|
178
- payload[:hits] = results.keys
181
+ payload[:hits] = results.keys.map { |name| normalize_key(name, options) }
179
182
  end
180
183
  end
181
184
  end
@@ -196,12 +199,13 @@ module ActiveSupport
196
199
  #
197
200
  # Failsafe: Raises errors.
198
201
  def delete_matched(matcher, options = nil)
199
- instrument :delete_matched, matcher do
200
- unless String === matcher
201
- raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}"
202
- end
202
+ unless String === matcher
203
+ raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}"
204
+ end
205
+ pattern = namespace_key(matcher, options)
206
+
207
+ instrument :delete_matched, pattern do
203
208
  redis.then do |c|
204
- pattern = namespace_key(matcher, options)
205
209
  cursor = "0"
206
210
  # Fetch keys in batches using SCAN to avoid blocking the Redis server.
207
211
  nodes = c.respond_to?(:nodes) ? c.nodes : [c]
@@ -234,10 +238,11 @@ module ActiveSupport
234
238
  #
235
239
  # Failsafe: Raises errors.
236
240
  def increment(name, amount = 1, options = nil)
237
- instrument :increment, name, amount: amount do
241
+ options = merged_options(options)
242
+ key = normalize_key(name, options)
243
+
244
+ instrument :increment, key, amount: amount do
238
245
  failsafe :increment do
239
- options = merged_options(options)
240
- key = normalize_key(name, options)
241
246
  change_counter(key, amount, options)
242
247
  end
243
248
  end
@@ -260,10 +265,11 @@ module ActiveSupport
260
265
  #
261
266
  # Failsafe: Raises errors.
262
267
  def decrement(name, amount = 1, options = nil)
263
- instrument :decrement, name, amount: amount do
268
+ options = merged_options(options)
269
+ key = normalize_key(name, options)
270
+
271
+ instrument :decrement, key, amount: amount do
264
272
  failsafe :decrement do
265
- options = merged_options(options)
266
- key = normalize_key(name, options)
267
273
  change_counter(key, -amount, options)
268
274
  end
269
275
  end
@@ -369,8 +375,8 @@ module ActiveSupport
369
375
  if pipeline
370
376
  pipeline.set(key, payload, **modifiers)
371
377
  else
372
- failsafe :write_entry, returning: false do
373
- redis.then { |c| c.set key, payload, **modifiers }
378
+ failsafe :write_entry, returning: nil do
379
+ redis.then { |c| !!c.set(key, payload, **modifiers) }
374
380
  end
375
381
  end
376
382
  end
@@ -63,28 +63,6 @@ module ActiveSupport
63
63
  end
64
64
  end
65
65
 
66
- module Marshal61WithFallback
67
- include SerializerWithFallback
68
- extend self
69
-
70
- MARSHAL_SIGNATURE = "\x04\x08".b.freeze
71
-
72
- def dump(entry)
73
- Marshal.dump(entry)
74
- end
75
-
76
- def dump_compressed(entry, threshold)
77
- Marshal.dump(entry.compressed(threshold))
78
- end
79
-
80
- alias_method :_load, :marshal_load
81
- public :_load
82
-
83
- def dumped?(dumped)
84
- dumped.start_with?(MARSHAL_SIGNATURE)
85
- end
86
- end
87
-
88
66
  module Marshal70WithFallback
89
67
  include SerializerWithFallback
90
68
  extend self
@@ -165,7 +143,6 @@ module ActiveSupport
165
143
 
166
144
  SERIALIZERS = {
167
145
  passthrough: PassthroughWithFallback,
168
- marshal_6_1: Marshal61WithFallback,
169
146
  marshal_7_0: Marshal70WithFallback,
170
147
  marshal_7_1: Marshal71WithFallback,
171
148
  message_pack: MessagePackWithFallback,