activesupport 8.1.0.beta1 → 8.1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +91 -0
- data/lib/active_support/callbacks.rb +20 -8
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/core_ext/array.rb +7 -7
- data/lib/active_support/core_ext/benchmark.rb +4 -11
- data/lib/active_support/core_ext/big_decimal.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +8 -6
- data/lib/active_support/core_ext/class.rb +2 -2
- data/lib/active_support/core_ext/date.rb +5 -5
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -35
- data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
- data/lib/active_support/core_ext/date_time.rb +5 -5
- data/lib/active_support/core_ext/digest.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +2 -2
- data/lib/active_support/core_ext/file.rb +1 -1
- data/lib/active_support/core_ext/hash.rb +8 -8
- data/lib/active_support/core_ext/integer.rb +3 -3
- data/lib/active_support/core_ext/kernel.rb +3 -3
- data/lib/active_support/core_ext/module.rb +11 -11
- data/lib/active_support/core_ext/numeric.rb +3 -3
- data/lib/active_support/core_ext/object.rb +13 -13
- data/lib/active_support/core_ext/pathname.rb +2 -2
- data/lib/active_support/core_ext/range.rb +4 -4
- data/lib/active_support/core_ext/string.rb +13 -13
- data/lib/active_support/core_ext/symbol.rb +1 -1
- data/lib/active_support/core_ext/time/calculations.rb +0 -7
- data/lib/active_support/core_ext/time/compatibility.rb +2 -27
- data/lib/active_support/core_ext/time.rb +5 -5
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/dependencies/interlock.rb +11 -5
- data/lib/active_support/dependencies.rb +6 -1
- data/lib/active_support/event_reporter.rb +24 -2
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +5 -2
- data/lib/active_support/json/encoding.rb +48 -19
- data/lib/active_support/log_subscriber.rb +0 -6
- data/lib/active_support/notifications/fanout.rb +64 -42
- data/lib/active_support/notifications/instrumenter.rb +1 -1
- data/lib/active_support/railtie.rb +7 -4
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +0 -5
- data/lib/active_support/testing/event_reporter_assertions.rb +11 -1
- data/lib/active_support/testing/parallelization/server.rb +15 -2
- data/lib/active_support/testing/parallelization/worker.rb +2 -2
- data/lib/active_support/testing/parallelization.rb +12 -1
- data/lib/active_support/time_with_zone.rb +3 -17
- data/lib/active_support/xml_mini.rb +2 -0
- data/lib/active_support.rb +12 -14
- metadata +18 -16
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
require_relative "string/conversions"
|
4
|
+
require_relative "string/filters"
|
5
|
+
require_relative "string/multibyte"
|
6
|
+
require_relative "string/starts_ends_with"
|
7
|
+
require_relative "string/inflections"
|
8
|
+
require_relative "string/access"
|
9
|
+
require_relative "string/behavior"
|
10
|
+
require_relative "string/output_safety"
|
11
|
+
require_relative "string/exclude"
|
12
|
+
require_relative "string/strip"
|
13
|
+
require_relative "string/inquiry"
|
14
|
+
require_relative "string/indent"
|
15
|
+
require_relative "string/zones"
|
@@ -224,13 +224,6 @@ class Time
|
|
224
224
|
# Returns a new Time representing the time a number of seconds since the instance time
|
225
225
|
def since(seconds)
|
226
226
|
self + seconds
|
227
|
-
rescue TypeError
|
228
|
-
result = to_datetime.since(seconds)
|
229
|
-
ActiveSupport.deprecator.warn(
|
230
|
-
"Passing an instance of #{seconds.class} to #{self.class}#since is deprecated. This behavior will raise " \
|
231
|
-
"a `TypeError` in Rails 8.1."
|
232
|
-
)
|
233
|
-
result
|
234
227
|
end
|
235
228
|
alias :in :since
|
236
229
|
|
@@ -8,33 +8,8 @@ class Time
|
|
8
8
|
|
9
9
|
silence_redefinition_of_method :to_time
|
10
10
|
|
11
|
-
#
|
12
|
-
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
11
|
+
# Return +self+.
|
13
12
|
def to_time
|
14
|
-
|
13
|
+
self
|
15
14
|
end
|
16
|
-
|
17
|
-
def preserve_timezone # :nodoc:
|
18
|
-
system_local_time? || super
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
def system_local_time?
|
23
|
-
if ::Time.equal?(self.class)
|
24
|
-
zone = self.zone
|
25
|
-
String === zone &&
|
26
|
-
(zone != "UTC" || active_support_local_zone == "UTC")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
@@active_support_local_tz = nil
|
31
|
-
|
32
|
-
def active_support_local_zone
|
33
|
-
@@active_support_local_zone = nil if @@active_support_local_tz != ENV["TZ"]
|
34
|
-
@@active_support_local_zone ||=
|
35
|
-
begin
|
36
|
-
@@active_support_local_tz = ENV["TZ"]
|
37
|
-
Time.new.zone
|
38
|
-
end
|
39
|
-
end
|
40
15
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
require_relative "time/acts_like"
|
4
|
+
require_relative "time/calculations"
|
5
|
+
require_relative "time/compatibility"
|
6
|
+
require_relative "time/conversions"
|
7
|
+
require_relative "time/zones"
|
@@ -10,19 +10,24 @@ module ActiveSupport # :nodoc:
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def loading(&block)
|
13
|
-
|
13
|
+
ActiveSupport.deprecator.warn(
|
14
|
+
"ActiveSupport::Dependencies::Interlock#loading is deprecated and " \
|
15
|
+
"will be removed in Rails 9.0. The loading interlock is no longer " \
|
16
|
+
"used since Rails switched to Zeitwerk for autoloading."
|
17
|
+
)
|
18
|
+
yield if block
|
14
19
|
end
|
15
20
|
|
16
21
|
def unloading(&block)
|
17
|
-
@lock.exclusive(purpose: :unload, compatible: [:
|
22
|
+
@lock.exclusive(purpose: :unload, compatible: [:unload], after_compatible: [:unload], &block)
|
18
23
|
end
|
19
24
|
|
20
25
|
def start_unloading
|
21
|
-
@lock.start_exclusive(purpose: :unload, compatible: [:
|
26
|
+
@lock.start_exclusive(purpose: :unload, compatible: [:unload])
|
22
27
|
end
|
23
28
|
|
24
29
|
def done_unloading
|
25
|
-
@lock.stop_exclusive(compatible: [:
|
30
|
+
@lock.stop_exclusive(compatible: [:unload])
|
26
31
|
end
|
27
32
|
|
28
33
|
def start_running
|
@@ -38,7 +43,8 @@ module ActiveSupport # :nodoc:
|
|
38
43
|
end
|
39
44
|
|
40
45
|
def permit_concurrent_loads(&block)
|
41
|
-
|
46
|
+
# Soft deprecated: no deprecation warning for now, but this is a no-op.
|
47
|
+
yield if block
|
42
48
|
end
|
43
49
|
|
44
50
|
def raw_state(&block) # :nodoc:
|
@@ -21,7 +21,12 @@ module ActiveSupport # :nodoc:
|
|
21
21
|
# preventing any other thread from being inside a #run_interlock
|
22
22
|
# block at the same time.
|
23
23
|
def self.load_interlock(&block)
|
24
|
-
|
24
|
+
ActiveSupport.deprecator.warn(
|
25
|
+
"ActiveSupport::Dependencies.load_interlock is deprecated and " \
|
26
|
+
"will be removed in Rails 9.0. The loading interlock is no longer " \
|
27
|
+
"used since Rails switched to Zeitwerk for autoloading."
|
28
|
+
)
|
29
|
+
yield if block
|
25
30
|
end
|
26
31
|
|
27
32
|
# Execute the supplied block while holding an exclusive lock,
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/parameter_filter"
|
4
|
+
|
3
5
|
module ActiveSupport
|
4
6
|
class TagStack # :nodoc:
|
5
7
|
EMPTY_TAGS = {}.freeze
|
@@ -260,6 +262,12 @@ module ActiveSupport
|
|
260
262
|
# # name: "user.created",
|
261
263
|
# # payload: { id: 123 },
|
262
264
|
# # }
|
265
|
+
#
|
266
|
+
# === Security
|
267
|
+
#
|
268
|
+
# When reporting events, Hash-based payloads are automatically filtered to remove sensitive data based on {Rails.application.filter_parameters}[https://guides.rubyonrails.org/configuring.html#config-filter-parameters].
|
269
|
+
#
|
270
|
+
# If an {event object}[rdoc-ref:EventReporter@Event+Objects] is given instead, subscribers will need to filter sensitive data themselves, e.g. with ActiveSupport::ParameterFilter.
|
263
271
|
class EventReporter
|
264
272
|
# Sets whether to raise an error if a subscriber raises an error during
|
265
273
|
# event emission, or when unexpected arguments are passed to +notify+.
|
@@ -267,6 +275,8 @@ module ActiveSupport
|
|
267
275
|
|
268
276
|
attr_writer :debug_mode # :nodoc:
|
269
277
|
|
278
|
+
attr_reader :subscribers # :nodoc
|
279
|
+
|
270
280
|
class << self
|
271
281
|
attr_accessor :context_store # :nodoc:
|
272
282
|
end
|
@@ -521,6 +531,11 @@ module ActiveSupport
|
|
521
531
|
context_store.context
|
522
532
|
end
|
523
533
|
|
534
|
+
def reload_payload_filter # :nodoc:
|
535
|
+
@payload_filter = nil
|
536
|
+
payload_filter
|
537
|
+
end
|
538
|
+
|
524
539
|
private
|
525
540
|
def raise_on_error?
|
526
541
|
@raise_on_error
|
@@ -530,6 +545,13 @@ module ActiveSupport
|
|
530
545
|
self.class.context_store
|
531
546
|
end
|
532
547
|
|
548
|
+
def payload_filter
|
549
|
+
@payload_filter ||= begin
|
550
|
+
mask = ActiveSupport::ParameterFilter::FILTERED
|
551
|
+
ActiveSupport::ParameterFilter.new(ActiveSupport.filter_parameters, mask: mask)
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
533
555
|
def resolve_name(name_or_object)
|
534
556
|
case name_or_object
|
535
557
|
when String, Symbol
|
@@ -544,9 +566,9 @@ module ActiveSupport
|
|
544
566
|
when String, Symbol
|
545
567
|
handle_unexpected_args(name_or_object, payload, kwargs) if payload && kwargs.any?
|
546
568
|
if kwargs.any?
|
547
|
-
kwargs.transform_keys(&:to_sym)
|
569
|
+
payload_filter.filter(kwargs.transform_keys(&:to_sym))
|
548
570
|
elsif payload
|
549
|
-
payload.transform_keys(&:to_sym)
|
571
|
+
payload_filter.filter(payload.transform_keys(&:to_sym))
|
550
572
|
end
|
551
573
|
else
|
552
574
|
handle_unexpected_args(name_or_object, payload, kwargs) if payload || kwargs.any?
|
@@ -123,7 +123,7 @@ module ActiveSupport
|
|
123
123
|
# healthy to consider this edge case because with mtimes in the future
|
124
124
|
# reloading is not triggered.
|
125
125
|
def max_mtime(paths)
|
126
|
-
time_now = Time.
|
126
|
+
time_now = Time.at(0, Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond), :nanosecond)
|
127
127
|
max_mtime = nil
|
128
128
|
|
129
129
|
# Time comparisons are performed with #compare_without_coercion because
|
@@ -55,11 +55,14 @@ module ActiveSupport
|
|
55
55
|
scope.current
|
56
56
|
end
|
57
57
|
|
58
|
-
def share_with(other)
|
58
|
+
def share_with(other, &block)
|
59
59
|
# Action Controller streaming spawns a new thread and copy thread locals.
|
60
60
|
# We do the same here for backward compatibility, but this is very much a hack
|
61
61
|
# and streaming should be rethought.
|
62
|
-
context.active_support_execution_state = other.active_support_execution_state.dup
|
62
|
+
old_state, context.active_support_execution_state = context.active_support_execution_state, other.active_support_execution_state.dup
|
63
|
+
block.call
|
64
|
+
ensure
|
65
|
+
context.active_support_execution_state = old_state
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
@@ -8,6 +8,7 @@ module ActiveSupport
|
|
8
8
|
delegate :use_standard_json_time_format, :use_standard_json_time_format=,
|
9
9
|
:time_precision, :time_precision=,
|
10
10
|
:escape_html_entities_in_json, :escape_html_entities_in_json=,
|
11
|
+
:escape_js_separators_in_json, :escape_js_separators_in_json=,
|
11
12
|
:json_encoder, :json_encoder=,
|
12
13
|
to: :'ActiveSupport::JSON::Encoding'
|
13
14
|
end
|
@@ -46,6 +47,8 @@ module ActiveSupport
|
|
46
47
|
def encode(value, options = nil)
|
47
48
|
if options.nil? || options.empty?
|
48
49
|
Encoding.encode_without_options(value)
|
50
|
+
elsif options == { escape: false }.freeze
|
51
|
+
Encoding.encode_without_escape(value)
|
49
52
|
else
|
50
53
|
Encoding.json_encoder.new(options).encode(value)
|
51
54
|
end
|
@@ -65,8 +68,9 @@ module ActiveSupport
|
|
65
68
|
"&".b => '\u0026'.b,
|
66
69
|
}
|
67
70
|
|
68
|
-
|
69
|
-
|
71
|
+
HTML_ENTITIES_REGEX = Regexp.union(*(ESCAPED_CHARS.keys - [U2028, U2029]))
|
72
|
+
FULL_ESCAPE_REGEX = Regexp.union(*ESCAPED_CHARS.keys)
|
73
|
+
JS_SEPARATORS_REGEX = Regexp.union(U2028, U2029)
|
70
74
|
|
71
75
|
class JSONGemEncoder # :nodoc:
|
72
76
|
attr_reader :options
|
@@ -84,14 +88,15 @@ module ActiveSupport
|
|
84
88
|
|
85
89
|
return json unless @options.fetch(:escape, true)
|
86
90
|
|
87
|
-
# Rails does more escaping than the JSON gem natively does (we
|
88
|
-
# escape \u2028 and \u2029 and optionally >, <, & to work around
|
89
|
-
# certain browser problems).
|
90
91
|
json.force_encoding(::Encoding::BINARY)
|
91
92
|
if @options.fetch(:escape_html_entities, Encoding.escape_html_entities_in_json)
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
if Encoding.escape_js_separators_in_json
|
94
|
+
json.gsub!(FULL_ESCAPE_REGEX, ESCAPED_CHARS)
|
95
|
+
else
|
96
|
+
json.gsub!(HTML_ENTITIES_REGEX, ESCAPED_CHARS)
|
97
|
+
end
|
98
|
+
elsif Encoding.escape_js_separators_in_json
|
99
|
+
json.gsub!(JS_SEPARATORS_REGEX, ESCAPED_CHARS)
|
95
100
|
end
|
96
101
|
json.force_encoding(::Encoding::UTF_8)
|
97
102
|
end
|
@@ -140,11 +145,14 @@ module ActiveSupport
|
|
140
145
|
end
|
141
146
|
end
|
142
147
|
|
143
|
-
|
148
|
+
# ruby/json 2.14.x yields non-String keys but doesn't let us know it's a key
|
149
|
+
if defined?(::JSON::Coder) && Gem::Version.new(::JSON::VERSION) >= Gem::Version.new("2.15")
|
144
150
|
class JSONGemCoderEncoder # :nodoc:
|
145
151
|
JSON_NATIVE_TYPES = [Hash, Array, Float, String, Symbol, Integer, NilClass, TrueClass, FalseClass, ::JSON::Fragment].freeze
|
146
|
-
CODER = ::JSON::Coder.new do |value|
|
152
|
+
CODER = ::JSON::Coder.new do |value, is_key|
|
147
153
|
json_value = value.as_json
|
154
|
+
# Keep compatibility by calling to_s on non-String keys
|
155
|
+
next json_value.to_s if is_key
|
148
156
|
# Handle objects returning self from as_json
|
149
157
|
if json_value.equal?(value)
|
150
158
|
next ::JSON::Fragment.new(::JSON.generate(json_value))
|
@@ -161,7 +169,14 @@ module ActiveSupport
|
|
161
169
|
|
162
170
|
|
163
171
|
def initialize(options = nil)
|
164
|
-
|
172
|
+
if options
|
173
|
+
options = options.dup
|
174
|
+
@escape = options.delete(:escape) { true }
|
175
|
+
@options = options.freeze
|
176
|
+
else
|
177
|
+
@escape = true
|
178
|
+
@options = {}.freeze
|
179
|
+
end
|
165
180
|
end
|
166
181
|
|
167
182
|
# Encode the given object into a JSON string
|
@@ -170,16 +185,17 @@ module ActiveSupport
|
|
170
185
|
|
171
186
|
json = CODER.dump(value)
|
172
187
|
|
173
|
-
return json unless @
|
188
|
+
return json unless @escape
|
174
189
|
|
175
|
-
# Rails does more escaping than the JSON gem natively does (we
|
176
|
-
# escape \u2028 and \u2029 and optionally >, <, & to work around
|
177
|
-
# certain browser problems).
|
178
190
|
json.force_encoding(::Encoding::BINARY)
|
179
191
|
if @options.fetch(:escape_html_entities, Encoding.escape_html_entities_in_json)
|
180
|
-
|
181
|
-
|
182
|
-
|
192
|
+
if Encoding.escape_js_separators_in_json
|
193
|
+
json.gsub!(FULL_ESCAPE_REGEX, ESCAPED_CHARS)
|
194
|
+
else
|
195
|
+
json.gsub!(HTML_ENTITIES_REGEX, ESCAPED_CHARS)
|
196
|
+
end
|
197
|
+
elsif Encoding.escape_js_separators_in_json
|
198
|
+
json.gsub!(JS_SEPARATORS_REGEX, ESCAPED_CHARS)
|
183
199
|
end
|
184
200
|
json.force_encoding(::Encoding::UTF_8)
|
185
201
|
end
|
@@ -195,6 +211,13 @@ module ActiveSupport
|
|
195
211
|
# as a safety measure.
|
196
212
|
attr_accessor :escape_html_entities_in_json
|
197
213
|
|
214
|
+
# If true, encode LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029)
|
215
|
+
# as escaped unicode sequences ('\u2028' and '\u2029').
|
216
|
+
# Historically these characters were not valid inside JavaScript strings
|
217
|
+
# but that changed in ECMAScript 2019. As such it's no longer a concern in
|
218
|
+
# modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.
|
219
|
+
attr_accessor :escape_js_separators_in_json
|
220
|
+
|
198
221
|
# Sets the precision of encoded time values.
|
199
222
|
# Defaults to 3 (equivalent to millisecond precision)
|
200
223
|
attr_accessor :time_precision
|
@@ -206,17 +229,23 @@ module ActiveSupport
|
|
206
229
|
def json_encoder=(encoder)
|
207
230
|
@json_encoder = encoder
|
208
231
|
@encoder_without_options = encoder.new
|
232
|
+
@encoder_without_escape = encoder.new(escape: false)
|
209
233
|
end
|
210
234
|
|
211
235
|
def encode_without_options(value) # :nodoc:
|
212
236
|
@encoder_without_options.encode(value)
|
213
237
|
end
|
238
|
+
|
239
|
+
def encode_without_escape(value) # :nodoc:
|
240
|
+
@encoder_without_escape.encode(value)
|
241
|
+
end
|
214
242
|
end
|
215
243
|
|
216
244
|
self.use_standard_json_time_format = true
|
217
245
|
self.escape_html_entities_in_json = true
|
246
|
+
self.escape_js_separators_in_json = true
|
218
247
|
self.json_encoder =
|
219
|
-
if defined?(
|
248
|
+
if defined?(JSONGemCoderEncoder)
|
220
249
|
JSONGemCoderEncoder
|
221
250
|
else
|
222
251
|
JSONGemEncoder
|
@@ -17,24 +17,30 @@ module ActiveSupport
|
|
17
17
|
|
18
18
|
module FanoutIteration # :nodoc:
|
19
19
|
private
|
20
|
-
def iterate_guarding_exceptions(collection)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
exceptions
|
27
|
-
exceptions << e
|
28
|
-
end
|
20
|
+
def iterate_guarding_exceptions(collection, &block)
|
21
|
+
case collection.size
|
22
|
+
when 0
|
23
|
+
when 1
|
24
|
+
collection.each(&block)
|
25
|
+
else
|
26
|
+
exceptions = nil
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
collection.each do |s|
|
29
|
+
yield s
|
30
|
+
rescue Exception => e
|
31
|
+
exceptions ||= []
|
32
|
+
exceptions << e
|
33
33
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
|
35
|
+
if exceptions
|
36
|
+
exceptions = exceptions.flat_map do |exception|
|
37
|
+
exception.is_a?(InstrumentationSubscriberError) ? exception.exceptions : [exception]
|
38
|
+
end
|
39
|
+
if exceptions.size == 1
|
40
|
+
raise exceptions.first
|
41
|
+
else
|
42
|
+
raise InstrumentationSubscriberError.new(exceptions), cause: exceptions.first
|
43
|
+
end
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
@@ -53,7 +59,6 @@ module ActiveSupport
|
|
53
59
|
@other_subscribers = []
|
54
60
|
@all_listeners_for = Concurrent::Map.new
|
55
61
|
@groups_for = Concurrent::Map.new
|
56
|
-
@silenceable_groups_for = Concurrent::Map.new
|
57
62
|
end
|
58
63
|
|
59
64
|
def inspect # :nodoc:
|
@@ -102,11 +107,9 @@ module ActiveSupport
|
|
102
107
|
if key
|
103
108
|
@all_listeners_for.delete(key)
|
104
109
|
@groups_for.delete(key)
|
105
|
-
@silenceable_groups_for.delete(key)
|
106
110
|
else
|
107
111
|
@all_listeners_for.clear
|
108
112
|
@groups_for.clear
|
109
|
-
@silenceable_groups_for.clear
|
110
113
|
end
|
111
114
|
end
|
112
115
|
|
@@ -184,25 +187,25 @@ module ActiveSupport
|
|
184
187
|
end
|
185
188
|
end
|
186
189
|
|
187
|
-
def
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
end
|
190
|
+
def group_listeners(listeners) # :nodoc:
|
191
|
+
listeners.group_by(&:group_class).transform_values do |s|
|
192
|
+
s.map(&:delegate).freeze
|
193
|
+
end.freeze
|
194
|
+
end
|
193
195
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
196
|
+
def groups_for(name) # :nodoc:
|
197
|
+
silenceable_groups, groups = @groups_for.compute_if_absent(name) do
|
198
|
+
listeners = all_listeners_for(name)
|
199
|
+
listeners.partition(&:silenceable).map { |l| group_listeners(l) }
|
198
200
|
end
|
199
201
|
|
200
202
|
unless silenceable_groups.empty?
|
201
|
-
groups = groups.dup
|
202
203
|
silenceable_groups.each do |group_class, subscriptions|
|
203
204
|
active_subscriptions = subscriptions.reject { |s| s.silenced?(name) }
|
204
205
|
unless active_subscriptions.empty?
|
205
|
-
groups
|
206
|
+
groups = groups.dup if groups.frozen?
|
207
|
+
base_groups = groups[group_class]
|
208
|
+
groups[group_class] = base_groups ? base_groups + active_subscriptions : active_subscriptions
|
206
209
|
end
|
207
210
|
end
|
208
211
|
end
|
@@ -227,13 +230,11 @@ module ActiveSupport
|
|
227
230
|
class Handle
|
228
231
|
include FanoutIteration
|
229
232
|
|
230
|
-
def initialize(notifier, name, id, payload) # :nodoc:
|
233
|
+
def initialize(notifier, name, id, groups, payload) # :nodoc:
|
231
234
|
@name = name
|
232
235
|
@id = id
|
233
236
|
@payload = payload
|
234
|
-
@groups =
|
235
|
-
group_klass.new(grouped_listeners, name, id, payload)
|
236
|
-
end
|
237
|
+
@groups = groups
|
237
238
|
@state = :initialized
|
238
239
|
end
|
239
240
|
|
@@ -267,10 +268,31 @@ module ActiveSupport
|
|
267
268
|
end
|
268
269
|
end
|
269
270
|
|
271
|
+
module NullHandle # :nodoc:
|
272
|
+
extend self
|
273
|
+
|
274
|
+
def start
|
275
|
+
end
|
276
|
+
|
277
|
+
def finish
|
278
|
+
end
|
279
|
+
|
280
|
+
def finish_with_values(_name, _id, _payload)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
270
284
|
include FanoutIteration
|
271
285
|
|
272
286
|
def build_handle(name, id, payload)
|
273
|
-
|
287
|
+
groups = groups_for(name).map do |group_klass, grouped_listeners|
|
288
|
+
group_klass.new(grouped_listeners, name, id, payload)
|
289
|
+
end
|
290
|
+
|
291
|
+
if groups.empty?
|
292
|
+
NullHandle
|
293
|
+
else
|
294
|
+
Handle.new(self, name, id, groups, payload)
|
295
|
+
end
|
274
296
|
end
|
275
297
|
|
276
298
|
def start(name, id, payload)
|
@@ -286,8 +308,8 @@ module ActiveSupport
|
|
286
308
|
handle.finish_with_values(name, id, payload)
|
287
309
|
end
|
288
310
|
|
289
|
-
def publish(name,
|
290
|
-
iterate_guarding_exceptions(listeners_for(name)) { |s| s.publish(name,
|
311
|
+
def publish(name, ...)
|
312
|
+
iterate_guarding_exceptions(listeners_for(name)) { |s| s.publish(name, ...) }
|
291
313
|
end
|
292
314
|
|
293
315
|
def publish_event(event)
|
@@ -387,9 +409,9 @@ module ActiveSupport
|
|
387
409
|
EventedGroup
|
388
410
|
end
|
389
411
|
|
390
|
-
def publish(
|
412
|
+
def publish(...)
|
391
413
|
if @can_publish
|
392
|
-
@delegate.publish
|
414
|
+
@delegate.publish(...)
|
393
415
|
end
|
394
416
|
end
|
395
417
|
|
@@ -419,8 +441,8 @@ module ActiveSupport
|
|
419
441
|
TimedGroup
|
420
442
|
end
|
421
443
|
|
422
|
-
def publish(
|
423
|
-
@delegate.call
|
444
|
+
def publish(...)
|
445
|
+
@delegate.call(...)
|
424
446
|
end
|
425
447
|
end
|
426
448
|
|
@@ -164,7 +164,7 @@ module ActiveSupport
|
|
164
164
|
@cpu_time_finish - @cpu_time_start
|
165
165
|
end
|
166
166
|
|
167
|
-
# Returns the idle time
|
167
|
+
# Returns the idle time (in milliseconds) passed between the call to
|
168
168
|
# #start! and the call to #finish!.
|
169
169
|
def idle_time
|
170
170
|
diff = duration - cpu_time
|
@@ -79,6 +79,13 @@ module ActiveSupport
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
+
initializer "active_support.set_filter_parameters" do |app|
|
83
|
+
config.after_initialize do
|
84
|
+
ActiveSupport.filter_parameters += Rails.application.config.filter_parameters
|
85
|
+
ActiveSupport.event_reporter.reload_payload_filter
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
82
89
|
initializer "active_support.deprecation_behavior" do |app|
|
83
90
|
if app.config.active_support.report_deprecations == false
|
84
91
|
app.deprecators.silenced = true
|
@@ -112,10 +119,6 @@ module ActiveSupport
|
|
112
119
|
config.eager_load_namespaces << TZInfo
|
113
120
|
end
|
114
121
|
|
115
|
-
initializer "active_support.to_time_preserves_timezone" do |app|
|
116
|
-
ActiveSupport.to_time_preserves_timezone = app.config.active_support.to_time_preserves_timezone
|
117
|
-
end
|
118
|
-
|
119
122
|
# Sets the default week start
|
120
123
|
# If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
|
121
124
|
initializer "active_support.initialize_beginning_of_week" do |app|
|