activesupport 6.0.0.rc1 → 6.0.3.rc1

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.

Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +165 -2
  3. data/README.rdoc +1 -1
  4. data/lib/active_support/backtrace_cleaner.rb +0 -1
  5. data/lib/active_support/cache.rb +29 -28
  6. data/lib/active_support/cache/file_store.rb +7 -8
  7. data/lib/active_support/cache/mem_cache_store.rb +8 -8
  8. data/lib/active_support/cache/memory_store.rb +8 -7
  9. data/lib/active_support/cache/null_store.rb +3 -3
  10. data/lib/active_support/cache/redis_cache_store.rb +8 -8
  11. data/lib/active_support/cache/strategy/local_cache.rb +23 -23
  12. data/lib/active_support/callbacks.rb +0 -3
  13. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  14. data/lib/active_support/concurrency/share_lock.rb +0 -1
  15. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  16. data/lib/active_support/core_ext/date_and_time/calculations.rb +0 -30
  17. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  18. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  19. data/lib/active_support/core_ext/digest.rb +3 -0
  20. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  21. data/lib/active_support/core_ext/hash/deep_transform_values.rb +2 -2
  22. data/lib/active_support/core_ext/module/delegation.rb +14 -1
  23. data/lib/active_support/core_ext/module/introspection.rb +1 -0
  24. data/lib/active_support/core_ext/object/duplicable.rb +7 -117
  25. data/lib/active_support/core_ext/object/try.rb +2 -0
  26. data/lib/active_support/core_ext/range/compare_range.rb +9 -3
  27. data/lib/active_support/core_ext/range/each.rb +0 -1
  28. data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
  29. data/lib/active_support/core_ext/string/filters.rb +1 -1
  30. data/lib/active_support/core_ext/string/output_safety.rb +2 -1
  31. data/lib/active_support/core_ext/time/calculations.rb +30 -0
  32. data/lib/active_support/dependencies.rb +35 -6
  33. data/lib/active_support/dependencies/zeitwerk_integration.rb +22 -4
  34. data/lib/active_support/deprecation/method_wrappers.rb +12 -6
  35. data/lib/active_support/deprecation/proxy_wrappers.rb +28 -3
  36. data/lib/active_support/descendants_tracker.rb +0 -1
  37. data/lib/active_support/duration.rb +15 -13
  38. data/lib/active_support/duration/iso8601_parser.rb +0 -1
  39. data/lib/active_support/duration/iso8601_serializer.rb +0 -1
  40. data/lib/active_support/encrypted_file.rb +1 -1
  41. data/lib/active_support/evented_file_update_checker.rb +11 -2
  42. data/lib/active_support/file_update_checker.rb +0 -1
  43. data/lib/active_support/gem_version.rb +1 -1
  44. data/lib/active_support/i18n_railtie.rb +4 -0
  45. data/lib/active_support/inflector/inflections.rb +0 -1
  46. data/lib/active_support/inflector/methods.rb +1 -2
  47. data/lib/active_support/inflector/transliterate.rb +27 -1
  48. data/lib/active_support/json/decoding.rb +0 -1
  49. data/lib/active_support/lazy_load_hooks.rb +0 -1
  50. data/lib/active_support/locale/en.rb +4 -2
  51. data/lib/active_support/log_subscriber.rb +0 -1
  52. data/lib/active_support/logger.rb +1 -1
  53. data/lib/active_support/logger_thread_safe_level.rb +2 -1
  54. data/lib/active_support/message_encryptor.rb +1 -1
  55. data/lib/active_support/message_verifier.rb +2 -2
  56. data/lib/active_support/messages/metadata.rb +3 -2
  57. data/lib/active_support/messages/rotator.rb +4 -4
  58. data/lib/active_support/multibyte/chars.rb +1 -2
  59. data/lib/active_support/multibyte/unicode.rb +0 -1
  60. data/lib/active_support/notifications/fanout.rb +2 -2
  61. data/lib/active_support/notifications/instrumenter.rb +4 -4
  62. data/lib/active_support/number_helper.rb +4 -0
  63. data/lib/active_support/number_helper/number_converter.rb +4 -5
  64. data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -8
  65. data/lib/active_support/number_helper/number_to_delimited_converter.rb +0 -1
  66. data/lib/active_support/number_helper/number_to_human_converter.rb +0 -1
  67. data/lib/active_support/number_helper/number_to_human_size_converter.rb +0 -1
  68. data/lib/active_support/number_helper/number_to_phone_converter.rb +0 -1
  69. data/lib/active_support/number_helper/number_to_rounded_converter.rb +0 -1
  70. data/lib/active_support/option_merger.rb +21 -3
  71. data/lib/active_support/ordered_hash.rb +1 -1
  72. data/lib/active_support/ordered_options.rb +5 -1
  73. data/lib/active_support/parameter_filter.rb +7 -3
  74. data/lib/active_support/string_inquirer.rb +0 -1
  75. data/lib/active_support/testing/parallelization.rb +16 -2
  76. data/lib/active_support/testing/stream.rb +0 -1
  77. data/lib/active_support/testing/time_helpers.rb +0 -2
  78. data/lib/active_support/xml_mini.rb +0 -1
  79. data/lib/active_support/xml_mini/jdom.rb +0 -1
  80. metadata +13 -9
@@ -28,7 +28,7 @@ module ActiveSupport
28
28
  # Provide support for raw values in the local cache strategy.
29
29
  module LocalCacheWithRaw # :nodoc:
30
30
  private
31
- def read_entry(key, options)
31
+ def read_entry(key, **options)
32
32
  entry = super
33
33
  if options[:raw] && local_cache && entry
34
34
  entry = deserialize_entry(entry.value)
@@ -36,11 +36,11 @@ module ActiveSupport
36
36
  entry
37
37
  end
38
38
 
39
- def write_entry(key, entry, options)
39
+ def write_entry(key, entry, **options)
40
40
  if options[:raw] && local_cache
41
41
  raw_entry = Entry.new(entry.value.to_s)
42
42
  raw_entry.expires_at = entry.expires_at
43
- super(key, raw_entry, options)
43
+ super(key, raw_entry, **options)
44
44
  else
45
45
  super
46
46
  end
@@ -142,12 +142,12 @@ module ActiveSupport
142
142
 
143
143
  private
144
144
  # Read an entry from the cache.
145
- def read_entry(key, options)
145
+ def read_entry(key, **options)
146
146
  rescue_error_with(nil) { deserialize_entry(@data.with { |c| c.get(key, options) }) }
147
147
  end
148
148
 
149
149
  # Write an entry to the cache.
150
- def write_entry(key, entry, options)
150
+ def write_entry(key, entry, **options)
151
151
  method = options && options[:unless_exist] ? :add : :set
152
152
  value = options[:raw] ? entry.value.to_s : entry
153
153
  expires_in = options[:expires_in].to_i
@@ -156,12 +156,12 @@ module ActiveSupport
156
156
  expires_in += 5.minutes
157
157
  end
158
158
  rescue_error_with false do
159
- @data.with { |c| c.send(method, key, value, expires_in, options) }
159
+ @data.with { |c| c.send(method, key, value, expires_in, **options) }
160
160
  end
161
161
  end
162
162
 
163
163
  # Reads multiple entries from the cache implementation.
164
- def read_multi_entries(names, options)
164
+ def read_multi_entries(names, **options)
165
165
  keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
166
166
 
167
167
  raw_values = @data.with { |c| c.get_multi(keys_to_names.keys) }
@@ -179,7 +179,7 @@ module ActiveSupport
179
179
  end
180
180
 
181
181
  # Delete an entry from the cache.
182
- def delete_entry(key, options)
182
+ def delete_entry(key, **options)
183
183
  rescue_error_with(false) { @data.with { |c| c.delete(key) } }
184
184
  end
185
185
 
@@ -51,7 +51,7 @@ module ActiveSupport
51
51
  keys = synchronize { @data.keys }
52
52
  keys.each do |key|
53
53
  entry = @data[key]
54
- delete_entry(key, options) if entry && entry.expired?
54
+ delete_entry(key, **options) if entry && entry.expired?
55
55
  end
56
56
  end
57
57
  end
@@ -67,7 +67,7 @@ module ActiveSupport
67
67
  instrument(:prune, target_size, from: @cache_size) do
68
68
  keys = synchronize { @key_access.keys.sort { |a, b| @key_access[a].to_f <=> @key_access[b].to_f } }
69
69
  keys.each do |key|
70
- delete_entry(key, options)
70
+ delete_entry(key, **options)
71
71
  return if @cache_size <= target_size || (max_time && Concurrent.monotonic_time - start_time > max_time)
72
72
  end
73
73
  end
@@ -98,7 +98,7 @@ module ActiveSupport
98
98
  matcher = key_matcher(matcher, options)
99
99
  keys = synchronize { @data.keys }
100
100
  keys.each do |key|
101
- delete_entry(key, options) if key.match(matcher)
101
+ delete_entry(key, **options) if key.match(matcher)
102
102
  end
103
103
  end
104
104
  end
@@ -114,17 +114,18 @@ module ActiveSupport
114
114
  end
115
115
 
116
116
  private
117
-
118
117
  PER_ENTRY_OVERHEAD = 240
119
118
 
120
119
  def cached_size(key, entry)
121
120
  key.to_s.bytesize + entry.size + PER_ENTRY_OVERHEAD
122
121
  end
123
122
 
124
- def read_entry(key, options)
123
+ def read_entry(key, **options)
125
124
  entry = @data[key]
126
125
  synchronize do
127
126
  if entry
127
+ entry = entry.dup
128
+ entry.dup_value!
128
129
  @key_access[key] = Time.now.to_f
129
130
  else
130
131
  @key_access.delete(key)
@@ -133,7 +134,7 @@ module ActiveSupport
133
134
  entry
134
135
  end
135
136
 
136
- def write_entry(key, entry, options)
137
+ def write_entry(key, entry, **options)
137
138
  entry.dup_value!
138
139
  synchronize do
139
140
  old_entry = @data[key]
@@ -150,7 +151,7 @@ module ActiveSupport
150
151
  end
151
152
  end
152
153
 
153
- def delete_entry(key, options)
154
+ def delete_entry(key, **options)
154
155
  synchronize do
155
156
  @key_access.delete(key)
156
157
  entry = @data.delete(key)
@@ -33,14 +33,14 @@ module ActiveSupport
33
33
  end
34
34
 
35
35
  private
36
- def read_entry(key, options)
36
+ def read_entry(key, **options)
37
37
  end
38
38
 
39
- def write_entry(key, entry, options)
39
+ def write_entry(key, entry, **options)
40
40
  true
41
41
  end
42
42
 
43
- def delete_entry(key, options)
43
+ def delete_entry(key, **options)
44
44
  false
45
45
  end
46
46
  end
@@ -74,7 +74,7 @@ module ActiveSupport
74
74
  # Support raw values in the local cache strategy.
75
75
  module LocalCacheWithRaw # :nodoc:
76
76
  private
77
- def read_entry(key, options)
77
+ def read_entry(key, **options)
78
78
  entry = super
79
79
  if options[:raw] && local_cache && entry
80
80
  entry = deserialize_entry(entry.value)
@@ -82,24 +82,24 @@ module ActiveSupport
82
82
  entry
83
83
  end
84
84
 
85
- def write_entry(key, entry, options)
85
+ def write_entry(key, entry, **options)
86
86
  if options[:raw] && local_cache
87
87
  raw_entry = Entry.new(serialize_entry(entry, raw: true))
88
88
  raw_entry.expires_at = entry.expires_at
89
- super(key, raw_entry, options)
89
+ super(key, raw_entry, **options)
90
90
  else
91
91
  super
92
92
  end
93
93
  end
94
94
 
95
- def write_multi_entries(entries, options)
95
+ def write_multi_entries(entries, **options)
96
96
  if options[:raw] && local_cache
97
97
  raw_entries = entries.map do |key, entry|
98
98
  raw_entry = Entry.new(serialize_entry(entry, raw: true))
99
99
  raw_entry.expires_at = entry.expires_at
100
100
  end.to_h
101
101
 
102
- super(raw_entries, options)
102
+ super(raw_entries, **options)
103
103
  else
104
104
  super
105
105
  end
@@ -346,13 +346,13 @@ module ActiveSupport
346
346
 
347
347
  # Store provider interface:
348
348
  # Read an entry from the cache.
349
- def read_entry(key, options = nil)
349
+ def read_entry(key, **options)
350
350
  failsafe :read_entry do
351
351
  deserialize_entry redis.with { |c| c.get(key) }
352
352
  end
353
353
  end
354
354
 
355
- def read_multi_entries(names, _options)
355
+ def read_multi_entries(names, **options)
356
356
  if mget_capable?
357
357
  read_multi_mget(*names)
358
358
  else
@@ -471,7 +471,7 @@ module ActiveSupport
471
471
 
472
472
  def failsafe(method, returning: nil)
473
473
  yield
474
- rescue ::Redis::BaseConnectionError => e
474
+ rescue ::Redis::BaseError => e
475
475
  handle_exception exception: e, method: method, returning: returning
476
476
  returning
477
477
  end
@@ -50,27 +50,27 @@ module ActiveSupport
50
50
  @data.clear
51
51
  end
52
52
 
53
- def read_entry(key, options)
53
+ def read_entry(key, **options)
54
54
  @data[key]
55
55
  end
56
56
 
57
- def read_multi_entries(keys, options)
57
+ def read_multi_entries(keys, **options)
58
58
  values = {}
59
59
 
60
60
  keys.each do |name|
61
- entry = read_entry(name, options)
61
+ entry = read_entry(name, **options)
62
62
  values[name] = entry.value if entry
63
63
  end
64
64
 
65
65
  values
66
66
  end
67
67
 
68
- def write_entry(key, value, options)
68
+ def write_entry(key, value, **options)
69
69
  @data[key] = value
70
70
  true
71
71
  end
72
72
 
73
- def delete_entry(key, options)
73
+ def delete_entry(key, **options)
74
74
  !!@data.delete(key)
75
75
  end
76
76
 
@@ -92,34 +92,34 @@ module ActiveSupport
92
92
  local_cache_key)
93
93
  end
94
94
 
95
- def clear(options = nil) # :nodoc:
95
+ def clear(**options) # :nodoc:
96
96
  return super unless cache = local_cache
97
97
  cache.clear(options)
98
98
  super
99
99
  end
100
100
 
101
- def cleanup(options = nil) # :nodoc:
101
+ def cleanup(**options) # :nodoc:
102
102
  return super unless cache = local_cache
103
103
  cache.clear
104
104
  super
105
105
  end
106
106
 
107
- def increment(name, amount = 1, options = nil) # :nodoc:
107
+ def increment(name, amount = 1, **options) # :nodoc:
108
108
  return super unless local_cache
109
109
  value = bypass_local_cache { super }
110
- write_cache_value(name, value, options)
110
+ write_cache_value(name, value, **options)
111
111
  value
112
112
  end
113
113
 
114
- def decrement(name, amount = 1, options = nil) # :nodoc:
114
+ def decrement(name, amount = 1, **options) # :nodoc:
115
115
  return super unless local_cache
116
116
  value = bypass_local_cache { super }
117
- write_cache_value(name, value, options)
117
+ write_cache_value(name, value, **options)
118
118
  value
119
119
  end
120
120
 
121
121
  private
122
- def read_entry(key, options)
122
+ def read_entry(key, **options)
123
123
  if cache = local_cache
124
124
  cache.fetch_entry(key) { super }
125
125
  else
@@ -127,42 +127,42 @@ module ActiveSupport
127
127
  end
128
128
  end
129
129
 
130
- def read_multi_entries(keys, options)
130
+ def read_multi_entries(keys, **options)
131
131
  return super unless local_cache
132
132
 
133
- local_entries = local_cache.read_multi_entries(keys, options)
133
+ local_entries = local_cache.read_multi_entries(keys, **options)
134
134
  missed_keys = keys - local_entries.keys
135
135
 
136
136
  if missed_keys.any?
137
- local_entries.merge!(super(missed_keys, options))
137
+ local_entries.merge!(super(missed_keys, **options))
138
138
  else
139
139
  local_entries
140
140
  end
141
141
  end
142
142
 
143
- def write_entry(key, entry, options)
143
+ def write_entry(key, entry, **options)
144
144
  if options[:unless_exist]
145
- local_cache.delete_entry(key, options) if local_cache
145
+ local_cache.delete_entry(key, **options) if local_cache
146
146
  else
147
- local_cache.write_entry(key, entry, options) if local_cache
147
+ local_cache.write_entry(key, entry, **options) if local_cache
148
148
  end
149
149
 
150
150
  super
151
151
  end
152
152
 
153
- def delete_entry(key, options)
154
- local_cache.delete_entry(key, options) if local_cache
153
+ def delete_entry(key, **options)
154
+ local_cache.delete_entry(key, **options) if local_cache
155
155
  super
156
156
  end
157
157
 
158
- def write_cache_value(name, value, options)
158
+ def write_cache_value(name, value, **options)
159
159
  name = normalize_key(name, options)
160
160
  cache = local_cache
161
161
  cache.mute do
162
162
  if value
163
- cache.write(name, value, options)
163
+ cache.write(name, value, **options)
164
164
  else
165
- cache.delete(name, options)
165
+ cache.delete(name, **options)
166
166
  end
167
167
  end
168
168
  end
@@ -142,7 +142,6 @@ module ActiveSupport
142
142
  end
143
143
 
144
144
  private
145
-
146
145
  # A hook invoked every time a before callback is halted.
147
146
  # This can be overridden in ActiveSupport::Callbacks implementors in order
148
147
  # to provide better debugging/logging.
@@ -582,7 +581,6 @@ module ActiveSupport
582
581
  attr_reader :chain
583
582
 
584
583
  private
585
-
586
584
  def append_one(callback)
587
585
  @callbacks = nil
588
586
  remove_duplicates(callback)
@@ -843,7 +841,6 @@ module ActiveSupport
843
841
  end
844
842
 
845
843
  protected
846
-
847
844
  def get_callbacks(name) # :nodoc:
848
845
  __callbacks[name.to_sym]
849
846
  end
@@ -7,11 +7,29 @@ module ActiveSupport
7
7
  # A monitor that will permit dependency loading while blocked waiting for
8
8
  # the lock.
9
9
  class LoadInterlockAwareMonitor < Monitor
10
+ EXCEPTION_NEVER = { Exception => :never }.freeze
11
+ EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
12
+ private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
13
+
10
14
  # Enters an exclusive section, but allows dependency loading while blocked
11
15
  def mon_enter
12
16
  mon_try_enter ||
13
17
  ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
14
18
  end
19
+
20
+ def synchronize
21
+ Thread.handle_interrupt(EXCEPTION_NEVER) do
22
+ mon_enter
23
+
24
+ begin
25
+ Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
26
+ yield
27
+ end
28
+ ensure
29
+ mon_exit
30
+ end
31
+ end
32
+ end
15
33
  end
16
34
  end
17
35
  end
@@ -200,7 +200,6 @@ module ActiveSupport
200
200
  end
201
201
 
202
202
  private
203
-
204
203
  # Must be called within synchronize
205
204
  def busy_for_exclusive?(purpose)
206
205
  busy_for_sharing?(purpose) ||
@@ -74,13 +74,13 @@ class Array
74
74
 
75
75
  case length
76
76
  when 0
77
- ""
77
+ +""
78
78
  when 1
79
- "#{self[0]}"
79
+ +"#{self[0]}"
80
80
  when 2
81
- "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
81
+ +"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
82
82
  else
83
- "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
83
+ +"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
84
84
  end
85
85
  end
86
86
 
@@ -181,7 +181,7 @@ class Array
181
181
  # </messages>
182
182
  #
183
183
  def to_xml(options = {})
184
- require "active_support/builder" unless defined?(Builder)
184
+ require "active_support/builder" unless defined?(Builder::XmlMarkup)
185
185
 
186
186
  options = options.dup
187
187
  options[:indent] ||= 2
@@ -20,21 +20,11 @@ module DateAndTime
20
20
  advance(days: -1)
21
21
  end
22
22
 
23
- # Returns a new date/time the specified number of days ago.
24
- def prev_day(days = 1)
25
- advance(days: -days)
26
- end
27
-
28
23
  # Returns a new date/time representing tomorrow.
29
24
  def tomorrow
30
25
  advance(days: 1)
31
26
  end
32
27
 
33
- # Returns a new date/time the specified number of days in the future.
34
- def next_day(days = 1)
35
- advance(days: days)
36
- end
37
-
38
28
  # Returns true if the date/time is today.
39
29
  def today?
40
30
  to_date == ::Date.current
@@ -198,21 +188,11 @@ module DateAndTime
198
188
  end
199
189
  end
200
190
 
201
- # Returns a new date/time the specified number of months in the future.
202
- def next_month(months = 1)
203
- advance(months: months)
204
- end
205
-
206
191
  # Short-hand for months_since(3)
207
192
  def next_quarter
208
193
  months_since(3)
209
194
  end
210
195
 
211
- # Returns a new date/time the specified number of years in the future.
212
- def next_year(years = 1)
213
- advance(years: years)
214
- end
215
-
216
196
  # Returns a new date/time representing the given day in the previous week.
217
197
  # Week is assumed to start on +start_day+, default is
218
198
  # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
@@ -233,11 +213,6 @@ module DateAndTime
233
213
  end
234
214
  alias_method :last_weekday, :prev_weekday
235
215
 
236
- # Returns a new date/time the specified number of months ago.
237
- def prev_month(months = 1)
238
- advance(months: -months)
239
- end
240
-
241
216
  # Short-hand for months_ago(1).
242
217
  def last_month
243
218
  months_ago(1)
@@ -249,11 +224,6 @@ module DateAndTime
249
224
  end
250
225
  alias_method :last_quarter, :prev_quarter
251
226
 
252
- # Returns a new date/time the specified number of years ago.
253
- def prev_year(years = 1)
254
- advance(years: -years)
255
- end
256
-
257
227
  # Short-hand for years_ago(1).
258
228
  def last_year
259
229
  years_ago(1)