activesupport 7.1.1 → 7.1.5
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 +201 -0
- data/lib/active_support/backtrace_cleaner.rb +5 -0
- data/lib/active_support/broadcast_logger.rb +23 -14
- data/lib/active_support/cache/entry.rb +7 -1
- data/lib/active_support/cache/file_store.rb +1 -1
- data/lib/active_support/cache/mem_cache_store.rb +16 -8
- data/lib/active_support/cache/memory_store.rb +4 -4
- data/lib/active_support/cache/redis_cache_store.rb +21 -14
- data/lib/active_support/cache/strategy/local_cache.rb +9 -6
- data/lib/active_support/cache.rb +36 -8
- data/lib/active_support/code_generator.rb +15 -10
- data/lib/active_support/core_ext/date/conversions.rb +1 -1
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +41 -26
- data/lib/active_support/core_ext/object/duplicable.rb +24 -15
- data/lib/active_support/core_ext/object/json.rb +5 -3
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +18 -16
- data/lib/active_support/deprecation/reporting.rb +8 -5
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/html_safe_translation.rb +16 -6
- data/lib/active_support/inflector/methods.rb +2 -2
- data/lib/active_support/log_subscriber.rb +9 -2
- data/lib/active_support/messages/codec.rb +1 -1
- data/lib/active_support/messages/metadata.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +25 -19
- data/lib/active_support/notifications/instrumenter.rb +11 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -2
- data/lib/active_support/number_helper.rb +379 -318
- data/lib/active_support/ordered_options.rb +2 -2
- data/lib/active_support/railtie.rb +3 -3
- data/lib/active_support/syntax_error_proxy.rb +12 -1
- data/lib/active_support/tagged_logging.rb +4 -0
- data/lib/active_support/testing/assertions.rb +1 -1
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/strict_warnings.rb +1 -0
- data/lib/active_support/testing/time_helpers.rb +5 -1
- data/lib/active_support/values/time_zone.rb +9 -0
- data/lib/active_support.rb +1 -1
- metadata +51 -9
|
@@ -9,16 +9,19 @@ module ActiveSupport
|
|
|
9
9
|
@cache = METHOD_CACHES[namespace]
|
|
10
10
|
@sources = []
|
|
11
11
|
@methods = {}
|
|
12
|
+
@canonical_methods = {}
|
|
12
13
|
end
|
|
13
14
|
|
|
14
|
-
def define_cached_method(
|
|
15
|
-
|
|
16
|
-
as = as.to_sym
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
def define_cached_method(canonical_name, as: nil)
|
|
16
|
+
canonical_name = canonical_name.to_sym
|
|
17
|
+
as = (as || canonical_name).to_sym
|
|
18
|
+
|
|
19
|
+
@methods.fetch(as) do
|
|
20
|
+
unless @cache.method_defined?(canonical_name) || @canonical_methods[canonical_name]
|
|
19
21
|
yield @sources
|
|
20
22
|
end
|
|
21
|
-
@
|
|
23
|
+
@canonical_methods[canonical_name] = true
|
|
24
|
+
@methods[as] = canonical_name
|
|
22
25
|
end
|
|
23
26
|
end
|
|
24
27
|
|
|
@@ -26,8 +29,10 @@ module ActiveSupport
|
|
|
26
29
|
unless @sources.empty?
|
|
27
30
|
@cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
|
|
28
31
|
end
|
|
29
|
-
@
|
|
30
|
-
|
|
32
|
+
@canonical_methods.clear
|
|
33
|
+
|
|
34
|
+
@methods.each do |as, canonical_name|
|
|
35
|
+
owner.define_method(as, @cache.instance_method(canonical_name))
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
end
|
|
@@ -52,8 +57,8 @@ module ActiveSupport
|
|
|
52
57
|
@namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
|
|
53
58
|
end
|
|
54
59
|
|
|
55
|
-
def define_cached_method(
|
|
56
|
-
@namespaces[namespace].define_cached_method(
|
|
60
|
+
def define_cached_method(canonical_name, namespace:, as: nil, &block)
|
|
61
|
+
@namespaces[namespace].define_cached_method(canonical_name, as: as, &block)
|
|
57
62
|
end
|
|
58
63
|
|
|
59
64
|
def execute
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require "active_support/concern"
|
|
4
4
|
|
|
5
5
|
class Module
|
|
6
|
-
#
|
|
6
|
+
# == Bite-sized separation of concerns
|
|
7
7
|
#
|
|
8
8
|
# We often find ourselves with a medium-sized chunk of behavior that we'd
|
|
9
9
|
# like to extract, but only mix in to a single class.
|
|
@@ -18,9 +18,9 @@ class Module
|
|
|
18
18
|
# with a comment, as a least-bad alternative. Using modules in separate files
|
|
19
19
|
# means tedious sifting to get a big-picture view.
|
|
20
20
|
#
|
|
21
|
-
#
|
|
21
|
+
# == Dissatisfying ways to separate small concerns
|
|
22
22
|
#
|
|
23
|
-
#
|
|
23
|
+
# === Using comments:
|
|
24
24
|
#
|
|
25
25
|
# class Todo < ApplicationRecord
|
|
26
26
|
# # Other todo implementation
|
|
@@ -37,7 +37,7 @@ class Module
|
|
|
37
37
|
# end
|
|
38
38
|
# end
|
|
39
39
|
#
|
|
40
|
-
#
|
|
40
|
+
# === With an inline module:
|
|
41
41
|
#
|
|
42
42
|
# Noisy syntax.
|
|
43
43
|
#
|
|
@@ -61,7 +61,7 @@ class Module
|
|
|
61
61
|
# include EventTracking
|
|
62
62
|
# end
|
|
63
63
|
#
|
|
64
|
-
#
|
|
64
|
+
# === Mix-in noise exiled to its own file:
|
|
65
65
|
#
|
|
66
66
|
# Once our chunk of behavior starts pushing the scroll-to-understand-it
|
|
67
67
|
# boundary, we give in and move it to a separate file. At this size, the
|
|
@@ -75,7 +75,7 @@ class Module
|
|
|
75
75
|
# include TodoEventTracking
|
|
76
76
|
# end
|
|
77
77
|
#
|
|
78
|
-
#
|
|
78
|
+
# == Introducing Module#concerning
|
|
79
79
|
#
|
|
80
80
|
# By quieting the mix-in noise, we arrive at a natural, low-ceremony way to
|
|
81
81
|
# separate bite-sized concerns.
|
|
@@ -317,37 +317,52 @@ class Module
|
|
|
317
317
|
# of <tt>object</tt> add or remove instance variables.
|
|
318
318
|
def delegate_missing_to(target, allow_nil: nil)
|
|
319
319
|
target = target.to_s
|
|
320
|
-
target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
|
|
320
|
+
target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target) || target == "__target"
|
|
321
321
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
if allow_nil
|
|
323
|
+
module_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
324
|
+
def respond_to_missing?(name, include_private = false)
|
|
325
|
+
# It may look like an oversight, but we deliberately do not pass
|
|
326
|
+
# +include_private+, because they do not get delegated.
|
|
326
327
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
return false if name == :marshal_dump || name == :_dump
|
|
329
|
+
#{target}.respond_to?(name) || super
|
|
330
|
+
end
|
|
330
331
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
332
|
+
def method_missing(method, *args, &block)
|
|
333
|
+
__target = #{target}
|
|
334
|
+
if __target.nil? && !nil.respond_to?(method)
|
|
335
|
+
nil
|
|
336
|
+
elsif __target.respond_to?(method)
|
|
337
|
+
__target.public_send(method, *args, &block)
|
|
338
|
+
else
|
|
336
339
|
super
|
|
337
|
-
rescue NoMethodError
|
|
338
|
-
if #{target}.nil?
|
|
339
|
-
if #{allow_nil == true}
|
|
340
|
-
nil
|
|
341
|
-
else
|
|
342
|
-
raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil"
|
|
343
|
-
end
|
|
344
|
-
else
|
|
345
|
-
raise
|
|
346
|
-
end
|
|
347
340
|
end
|
|
348
341
|
end
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
342
|
+
ruby2_keywords(:method_missing)
|
|
343
|
+
RUBY
|
|
344
|
+
else
|
|
345
|
+
module_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
346
|
+
def respond_to_missing?(name, include_private = false)
|
|
347
|
+
# It may look like an oversight, but we deliberately do not pass
|
|
348
|
+
# +include_private+, because they do not get delegated.
|
|
349
|
+
|
|
350
|
+
return false if name == :marshal_dump || name == :_dump
|
|
351
|
+
#{target}.respond_to?(name) || super
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def method_missing(method, *args, &block)
|
|
355
|
+
__target = #{target}
|
|
356
|
+
if __target.nil? && !nil.respond_to?(method)
|
|
357
|
+
raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil"
|
|
358
|
+
elsif __target.respond_to?(method)
|
|
359
|
+
__target.public_send(method, *args, &block)
|
|
360
|
+
else
|
|
361
|
+
super
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
ruby2_keywords(:method_missing)
|
|
365
|
+
RUBY
|
|
366
|
+
end
|
|
352
367
|
end
|
|
353
368
|
end
|
|
@@ -28,23 +28,32 @@ class Object
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def duplicable?
|
|
37
|
-
false
|
|
38
|
-
end
|
|
31
|
+
methods_are_duplicable = begin
|
|
32
|
+
Object.instance_method(:duplicable?).dup
|
|
33
|
+
true
|
|
34
|
+
rescue TypeError
|
|
35
|
+
false
|
|
39
36
|
end
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
unless methods_are_duplicable
|
|
39
|
+
class Method
|
|
40
|
+
# Methods are not duplicable:
|
|
41
|
+
#
|
|
42
|
+
# method(:puts).duplicable? # => false
|
|
43
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
|
44
|
+
def duplicable?
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class UnboundMethod
|
|
50
|
+
# Unbound methods are not duplicable:
|
|
51
|
+
#
|
|
52
|
+
# method(:puts).unbind.duplicable? # => false
|
|
53
|
+
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
|
54
|
+
def duplicable?
|
|
55
|
+
false
|
|
56
|
+
end
|
|
48
57
|
end
|
|
49
58
|
end
|
|
50
59
|
|
|
@@ -233,9 +233,11 @@ class Pathname # :nodoc:
|
|
|
233
233
|
end
|
|
234
234
|
end
|
|
235
235
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
236
|
+
unless IPAddr.method_defined?(:as_json, false)
|
|
237
|
+
class IPAddr # :nodoc:
|
|
238
|
+
def as_json(options = nil)
|
|
239
|
+
to_s
|
|
240
|
+
end
|
|
239
241
|
end
|
|
240
242
|
end
|
|
241
243
|
|
|
@@ -68,7 +68,7 @@ class Object
|
|
|
68
68
|
# You can access these methods using the class name instead:
|
|
69
69
|
#
|
|
70
70
|
# class Phone < ActiveRecord::Base
|
|
71
|
-
# enum phone_number_type
|
|
71
|
+
# enum :phone_number_type, { home: 0, office: 1, mobile: 2 }
|
|
72
72
|
#
|
|
73
73
|
# with_options presence: true do
|
|
74
74
|
# validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
|
|
@@ -24,7 +24,7 @@ class String
|
|
|
24
24
|
#
|
|
25
25
|
# The second argument, +indent_string+, specifies which indent string to
|
|
26
26
|
# use. The default is +nil+, which tells the method to make a guess by
|
|
27
|
-
# peeking at the first indented line, and
|
|
27
|
+
# peeking at the first indented line, and fall back to a space if there is
|
|
28
28
|
# none.
|
|
29
29
|
#
|
|
30
30
|
# " foo".indent(2) # => " foo"
|
|
@@ -57,15 +57,15 @@ module ActiveSupport
|
|
|
57
57
|
# You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+
|
|
58
58
|
# constant. Available behaviors are:
|
|
59
59
|
#
|
|
60
|
-
# [
|
|
61
|
-
# [
|
|
62
|
-
# [
|
|
63
|
-
# [
|
|
64
|
-
# [
|
|
65
|
-
# [
|
|
60
|
+
# [+:raise+] Raise ActiveSupport::DeprecationException.
|
|
61
|
+
# [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
|
|
62
|
+
# [+:log+] Log all deprecation warnings to +Rails.logger+.
|
|
63
|
+
# [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
|
|
64
|
+
# [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
|
|
65
|
+
# [+:silence+] Do nothing. On \Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
|
|
66
66
|
#
|
|
67
67
|
# Setting behaviors only affects deprecations that happen after boot time.
|
|
68
|
-
# For more information you can read the documentation of the
|
|
68
|
+
# For more information you can read the documentation of the #behavior= method.
|
|
69
69
|
module Behavior
|
|
70
70
|
# Whether to print a backtrace along with the warning.
|
|
71
71
|
attr_accessor :debug
|
|
@@ -85,12 +85,12 @@ module ActiveSupport
|
|
|
85
85
|
#
|
|
86
86
|
# Available behaviors:
|
|
87
87
|
#
|
|
88
|
-
# [
|
|
89
|
-
# [
|
|
90
|
-
# [
|
|
91
|
-
# [
|
|
92
|
-
# [
|
|
93
|
-
# [
|
|
88
|
+
# [+:raise+] Raise ActiveSupport::DeprecationException.
|
|
89
|
+
# [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
|
|
90
|
+
# [+:log+] Log all deprecation warnings to +Rails.logger+.
|
|
91
|
+
# [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
|
|
92
|
+
# [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
|
|
93
|
+
# [+:silence+] Do nothing.
|
|
94
94
|
#
|
|
95
95
|
# Setting behaviors only affects deprecations that happen after boot time.
|
|
96
96
|
# Deprecation warnings raised by gems are not affected by this setting
|
|
@@ -104,15 +104,17 @@ module ActiveSupport
|
|
|
104
104
|
# # custom stuff
|
|
105
105
|
# }
|
|
106
106
|
#
|
|
107
|
-
# If you are using \Rails, you can set
|
|
108
|
-
#
|
|
107
|
+
# If you are using \Rails, you can set
|
|
108
|
+
# <tt>config.active_support.report_deprecations = false</tt> to disable
|
|
109
|
+
# all deprecation behaviors. This is similar to the +:silence+ option but
|
|
110
|
+
# more performant.
|
|
109
111
|
def behavior=(behavior)
|
|
110
112
|
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
|
111
113
|
end
|
|
112
114
|
|
|
113
115
|
# Sets the behavior for disallowed deprecations (those configured by
|
|
114
116
|
# ActiveSupport::Deprecation#disallowed_warnings=) to the specified
|
|
115
|
-
# value. As with
|
|
117
|
+
# value. As with #behavior=, this can be a single value, array, or an
|
|
116
118
|
# object that responds to +call+.
|
|
117
119
|
def disallowed_behavior=(behavior)
|
|
118
120
|
@disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
|
@@ -142,7 +142,9 @@ module ActiveSupport
|
|
|
142
142
|
return _extract_callstack(callstack) if callstack.first.is_a? String
|
|
143
143
|
|
|
144
144
|
offending_line = callstack.find { |frame|
|
|
145
|
-
|
|
145
|
+
# Code generated with `eval` doesn't have an `absolute_path`, e.g. templates.
|
|
146
|
+
path = frame.absolute_path || frame.path
|
|
147
|
+
path && !ignored_callstack?(path)
|
|
146
148
|
} || callstack.first
|
|
147
149
|
|
|
148
150
|
[offending_line.path, offending_line.lineno, offending_line.label]
|
|
@@ -150,7 +152,7 @@ module ActiveSupport
|
|
|
150
152
|
|
|
151
153
|
def _extract_callstack(callstack)
|
|
152
154
|
warn "Please pass `caller_locations` to the deprecation API" if $VERBOSE
|
|
153
|
-
offending_line = callstack.find { |line| !ignored_callstack(line) } || callstack.first
|
|
155
|
+
offending_line = callstack.find { |line| !ignored_callstack?(line) } || callstack.first
|
|
154
156
|
|
|
155
157
|
if offending_line
|
|
156
158
|
if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
|
|
@@ -161,10 +163,11 @@ module ActiveSupport
|
|
|
161
163
|
end
|
|
162
164
|
end
|
|
163
165
|
|
|
164
|
-
RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__) + "/"
|
|
166
|
+
RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__) + "/" # :nodoc:
|
|
167
|
+
LIB_DIR = RbConfig::CONFIG["libdir"] # :nodoc:
|
|
165
168
|
|
|
166
|
-
def ignored_callstack(path)
|
|
167
|
-
path.start_with?(RAILS_GEM_ROOT
|
|
169
|
+
def ignored_callstack?(path)
|
|
170
|
+
path.start_with?(RAILS_GEM_ROOT, LIB_DIR)
|
|
168
171
|
end
|
|
169
172
|
end
|
|
170
173
|
end
|
|
@@ -7,18 +7,28 @@ module ActiveSupport
|
|
|
7
7
|
def translate(key, **options)
|
|
8
8
|
if html_safe_translation_key?(key)
|
|
9
9
|
html_safe_options = html_escape_translation_options(options)
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
|
|
11
|
+
exception = false
|
|
12
|
+
exception_handler = ->(*args) do
|
|
13
|
+
exception = true
|
|
14
|
+
I18n.exception_handler.call(*args)
|
|
15
|
+
end
|
|
16
|
+
translation = I18n.translate(key, **html_safe_options, exception_handler: exception_handler)
|
|
17
|
+
if exception
|
|
18
|
+
translation
|
|
19
|
+
else
|
|
20
|
+
html_safe_translation(translation)
|
|
21
|
+
end
|
|
12
22
|
else
|
|
13
23
|
I18n.translate(key, **options)
|
|
14
24
|
end
|
|
15
25
|
end
|
|
16
26
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
27
|
+
def html_safe_translation_key?(key)
|
|
28
|
+
/(?:_|\b)html\z/.match?(key)
|
|
29
|
+
end
|
|
21
30
|
|
|
31
|
+
private
|
|
22
32
|
def html_escape_translation_options(options)
|
|
23
33
|
options.each do |name, value|
|
|
24
34
|
unless i18n_option?(name) || (name == :count && value.is_a?(Numeric))
|
|
@@ -164,7 +164,7 @@ module ActiveSupport
|
|
|
164
164
|
# upcase_first('w') # => "W"
|
|
165
165
|
# upcase_first('') # => ""
|
|
166
166
|
def upcase_first(string)
|
|
167
|
-
string.length > 0 ? string[0].upcase.concat(string[1..-1]) : ""
|
|
167
|
+
string.length > 0 ? string[0].upcase.concat(string[1..-1]) : +""
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
# Converts the first character in the string to lowercase.
|
|
@@ -173,7 +173,7 @@ module ActiveSupport
|
|
|
173
173
|
# downcase_first('I') # => "i"
|
|
174
174
|
# downcase_first('') # => ""
|
|
175
175
|
def downcase_first(string)
|
|
176
|
-
string.length > 0 ? string[0].downcase.concat(string[1..-1]) : ""
|
|
176
|
+
string.length > 0 ? string[0].downcase.concat(string[1..-1]) : +""
|
|
177
177
|
end
|
|
178
178
|
|
|
179
179
|
# Capitalizes all the words and replaces some characters in the string to
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/module/attribute_accessors"
|
|
4
4
|
require "active_support/core_ext/class/attribute"
|
|
5
|
+
require "active_support/core_ext/enumerable"
|
|
5
6
|
require "active_support/subscriber"
|
|
6
7
|
require "active_support/deprecation/proxy_wrappers"
|
|
7
8
|
|
|
@@ -86,6 +87,12 @@ module ActiveSupport
|
|
|
86
87
|
mattr_accessor :colorize_logging, default: true
|
|
87
88
|
class_attribute :log_levels, instance_accessor: false, default: {} # :nodoc:
|
|
88
89
|
|
|
90
|
+
LEVEL_CHECKS = {
|
|
91
|
+
debug: -> (logger) { !logger.debug? },
|
|
92
|
+
info: -> (logger) { !logger.info? },
|
|
93
|
+
error: -> (logger) { !logger.error? },
|
|
94
|
+
}
|
|
95
|
+
|
|
89
96
|
class << self
|
|
90
97
|
def logger
|
|
91
98
|
@logger ||= if defined?(Rails) && Rails.respond_to?(:logger)
|
|
@@ -122,7 +129,7 @@ module ActiveSupport
|
|
|
122
129
|
end
|
|
123
130
|
|
|
124
131
|
def subscribe_log_level(method, level)
|
|
125
|
-
self.log_levels = log_levels.merge(method =>
|
|
132
|
+
self.log_levels = log_levels.merge(method => LEVEL_CHECKS.fetch(level))
|
|
126
133
|
set_event_levels
|
|
127
134
|
end
|
|
128
135
|
end
|
|
@@ -137,7 +144,7 @@ module ActiveSupport
|
|
|
137
144
|
end
|
|
138
145
|
|
|
139
146
|
def silenced?(event)
|
|
140
|
-
logger.nil? ||
|
|
147
|
+
logger.nil? || @event_levels[event]&.call(logger)
|
|
141
148
|
end
|
|
142
149
|
|
|
143
150
|
def call(event)
|
|
@@ -28,7 +28,7 @@ module ActiveSupport
|
|
|
28
28
|
|
|
29
29
|
def decode(encoded, url_safe: @url_safe)
|
|
30
30
|
url_safe ? ::Base64.urlsafe_decode64(encoded) : ::Base64.strict_decode64(encoded)
|
|
31
|
-
rescue
|
|
31
|
+
rescue StandardError => error
|
|
32
32
|
throw :invalid_message_format, error
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -18,26 +18,30 @@ module ActiveSupport
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
module FanoutIteration # :nodoc:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
listeners.each do |s|
|
|
25
|
-
yield s
|
|
26
|
-
rescue Exception => e
|
|
27
|
-
exceptions ||= []
|
|
28
|
-
exceptions << e
|
|
29
|
-
end
|
|
21
|
+
private
|
|
22
|
+
def iterate_guarding_exceptions(collection)
|
|
23
|
+
exceptions = nil
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
collection.each do |s|
|
|
26
|
+
yield s
|
|
27
|
+
rescue Exception => e
|
|
28
|
+
exceptions ||= []
|
|
29
|
+
exceptions << e
|
|
36
30
|
end
|
|
37
|
-
end
|
|
38
31
|
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
if exceptions
|
|
33
|
+
exceptions = exceptions.flat_map do |exception|
|
|
34
|
+
exception.is_a?(InstrumentationSubscriberError) ? exception.exceptions : [exception]
|
|
35
|
+
end
|
|
36
|
+
if exceptions.size == 1
|
|
37
|
+
raise exceptions.first
|
|
38
|
+
else
|
|
39
|
+
raise InstrumentationSubscriberError.new(exceptions), cause: exceptions.first
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
collection
|
|
44
|
+
end
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
# This is a default queue implementation that ships with Notifications.
|
|
@@ -225,6 +229,8 @@ module ActiveSupport
|
|
|
225
229
|
# handle.finish
|
|
226
230
|
# end
|
|
227
231
|
class Handle
|
|
232
|
+
include FanoutIteration
|
|
233
|
+
|
|
228
234
|
def initialize(notifier, name, id, payload) # :nodoc:
|
|
229
235
|
@name = name
|
|
230
236
|
@id = id
|
|
@@ -239,7 +245,7 @@ module ActiveSupport
|
|
|
239
245
|
ensure_state! :initialized
|
|
240
246
|
@state = :started
|
|
241
247
|
|
|
242
|
-
@groups
|
|
248
|
+
iterate_guarding_exceptions(@groups) do |group|
|
|
243
249
|
group.start(@name, @id, @payload)
|
|
244
250
|
end
|
|
245
251
|
end
|
|
@@ -252,7 +258,7 @@ module ActiveSupport
|
|
|
252
258
|
ensure_state! :started
|
|
253
259
|
@state = :finished
|
|
254
260
|
|
|
255
|
-
@groups
|
|
261
|
+
iterate_guarding_exceptions(@groups) do |group|
|
|
256
262
|
group.finish(name, id, payload)
|
|
257
263
|
end
|
|
258
264
|
end
|
|
@@ -104,7 +104,7 @@ module ActiveSupport
|
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
class Event
|
|
107
|
-
attr_reader :name, :
|
|
107
|
+
attr_reader :name, :transaction_id
|
|
108
108
|
attr_accessor :payload
|
|
109
109
|
|
|
110
110
|
def initialize(name, start, ending, transaction_id, payload)
|
|
@@ -119,7 +119,15 @@ module ActiveSupport
|
|
|
119
119
|
@allocation_count_finish = 0
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
def
|
|
122
|
+
def time
|
|
123
|
+
@time / 1000.0 if @time
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def end
|
|
127
|
+
@end / 1000.0 if @end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def record # :nodoc:
|
|
123
131
|
start!
|
|
124
132
|
begin
|
|
125
133
|
yield payload if block_given?
|
|
@@ -195,7 +203,7 @@ module ActiveSupport
|
|
|
195
203
|
#
|
|
196
204
|
# @event.duration # => 1000.138
|
|
197
205
|
def duration
|
|
198
|
-
|
|
206
|
+
@end - @time
|
|
199
207
|
end
|
|
200
208
|
|
|
201
209
|
private
|
|
@@ -43,13 +43,13 @@ module ActiveSupport
|
|
|
43
43
|
|
|
44
44
|
def exponent
|
|
45
45
|
max = STORAGE_UNITS.size - 1
|
|
46
|
-
exp = (Math.log(number) / Math.log(base)).to_i
|
|
46
|
+
exp = (Math.log(number.abs) / Math.log(base)).to_i
|
|
47
47
|
exp = max if exp > max # avoid overflow for the highest unit
|
|
48
48
|
exp
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def smaller_than_base?
|
|
52
|
-
number.to_i < base
|
|
52
|
+
number.to_i.abs < base
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def base
|