activesupport 7.0.0.alpha2 → 7.0.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +80 -0
- data/lib/active_support/cache/mem_cache_store.rb +9 -5
- data/lib/active_support/cache/memory_store.rb +2 -2
- data/lib/active_support/cache/redis_cache_store.rb +3 -8
- data/lib/active_support/cache/strategy/local_cache.rb +6 -12
- data/lib/active_support/callbacks.rb +145 -50
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/core_ext/array/conversions.rb +3 -1
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/class/subclasses.rb +4 -2
- data/lib/active_support/core_ext/date/calculations.rb +2 -2
- data/lib/active_support/core_ext/date/conversions.rb +3 -3
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +5 -5
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +26 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/numeric/conversions.rb +78 -75
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/with_options.rb +20 -1
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/time/calculations.rb +1 -1
- data/lib/active_support/core_ext/time/conversions.rb +4 -3
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +2 -2
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -13
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/current_attributes.rb +26 -25
- data/lib/active_support/descendants_tracker.rb +175 -69
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +30 -4
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +18 -9
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +12 -3
- data/lib/active_support/inflector/methods.rb +2 -2
- data/lib/active_support/isolated_execution_state.rb +56 -0
- data/lib/active_support/logger_thread_safe_level.rb +2 -3
- data/lib/active_support/message_encryptor.rb +5 -0
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/notifications/fanout.rb +61 -55
- data/lib/active_support/notifications/instrumenter.rb +15 -15
- data/lib/active_support/notifications.rb +5 -21
- data/lib/active_support/option_merger.rb +4 -0
- data/lib/active_support/per_thread_registry.rb +4 -0
- data/lib/active_support/railtie.rb +38 -11
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/subscriber.rb +2 -18
- data/lib/active_support/tagged_logging.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +1 -1
- data/lib/active_support/time_with_zone.rb +34 -6
- data/lib/active_support/values/time_zone.rb +5 -0
- data/lib/active_support/xml_mini.rb +3 -3
- data/lib/active_support.rb +7 -4
- metadata +23 -6
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module ExecutionContext # :nodoc:
|
5
|
+
@after_change_callbacks = []
|
6
|
+
class << self
|
7
|
+
def after_change(&block)
|
8
|
+
@after_change_callbacks << block
|
9
|
+
end
|
10
|
+
|
11
|
+
# Updates the execution context. If a block is given, it resets the provided keys to their
|
12
|
+
# previous value once the block exits.
|
13
|
+
def set(**options)
|
14
|
+
options.symbolize_keys!
|
15
|
+
keys = options.keys
|
16
|
+
|
17
|
+
store = self.store
|
18
|
+
|
19
|
+
previous_context = keys.zip(store.values_at(*keys)).to_h
|
20
|
+
|
21
|
+
store.merge!(options)
|
22
|
+
@after_change_callbacks.each(&:call)
|
23
|
+
|
24
|
+
if block_given?
|
25
|
+
begin
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
store.merge!(previous_context)
|
29
|
+
@after_change_callbacks.each(&:call)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def []=(key, value)
|
35
|
+
store[key.to_sym] = value
|
36
|
+
@after_change_callbacks.each(&:call)
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_h
|
40
|
+
store.dup
|
41
|
+
end
|
42
|
+
|
43
|
+
def clear
|
44
|
+
store.clear
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def store
|
49
|
+
IsolatedExecutionState[:active_support_execution_context] ||= {}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/error_reporter"
|
3
4
|
require "active_support/callbacks"
|
4
5
|
require "concurrent/hash"
|
5
6
|
|
@@ -86,15 +87,32 @@ module ActiveSupport
|
|
86
87
|
instance = run!
|
87
88
|
begin
|
88
89
|
yield
|
90
|
+
rescue => error
|
91
|
+
error_reporter.report(error, handled: false)
|
92
|
+
raise
|
89
93
|
ensure
|
90
94
|
instance.complete!
|
91
95
|
end
|
92
96
|
end
|
93
97
|
|
98
|
+
def self.perform # :nodoc:
|
99
|
+
instance = new
|
100
|
+
instance.run
|
101
|
+
begin
|
102
|
+
yield
|
103
|
+
ensure
|
104
|
+
instance.complete
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
94
108
|
class << self # :nodoc:
|
95
109
|
attr_accessor :active
|
96
110
|
end
|
97
111
|
|
112
|
+
def self.error_reporter
|
113
|
+
@error_reporter ||= ActiveSupport::ErrorReporter.new
|
114
|
+
end
|
115
|
+
|
98
116
|
def self.inherited(other) # :nodoc:
|
99
117
|
super
|
100
118
|
other.active = Concurrent::Hash.new
|
@@ -103,11 +121,15 @@ module ActiveSupport
|
|
103
121
|
self.active = Concurrent::Hash.new
|
104
122
|
|
105
123
|
def self.active? # :nodoc:
|
106
|
-
@active[
|
124
|
+
@active[IsolatedExecutionState.unique_id]
|
107
125
|
end
|
108
126
|
|
109
127
|
def run! # :nodoc:
|
110
|
-
self.class.active[
|
128
|
+
self.class.active[IsolatedExecutionState.unique_id] = true
|
129
|
+
run
|
130
|
+
end
|
131
|
+
|
132
|
+
def run # :nodoc:
|
111
133
|
run_callbacks(:run)
|
112
134
|
end
|
113
135
|
|
@@ -116,9 +138,13 @@ module ActiveSupport
|
|
116
138
|
#
|
117
139
|
# Where possible, prefer +wrap+.
|
118
140
|
def complete!
|
119
|
-
|
141
|
+
complete
|
120
142
|
ensure
|
121
|
-
self.class.active.delete
|
143
|
+
self.class.active.delete(IsolatedExecutionState.unique_id)
|
144
|
+
end
|
145
|
+
|
146
|
+
def complete # :nodoc:
|
147
|
+
run_callbacks(:complete)
|
122
148
|
end
|
123
149
|
|
124
150
|
private
|
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
4
|
module ForkTracker # :nodoc:
|
5
|
+
module ModernCoreExt
|
6
|
+
def _fork
|
7
|
+
pid = super
|
8
|
+
if pid == 0
|
9
|
+
ForkTracker.check!
|
10
|
+
end
|
11
|
+
pid
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
module CoreExt
|
6
16
|
def fork(...)
|
7
17
|
if block_given?
|
@@ -20,11 +30,7 @@ module ActiveSupport
|
|
20
30
|
|
21
31
|
module CoreExtPrivate
|
22
32
|
include CoreExt
|
23
|
-
|
24
|
-
private
|
25
|
-
def fork(...)
|
26
|
-
super
|
27
|
-
end
|
33
|
+
private :fork
|
28
34
|
end
|
29
35
|
|
30
36
|
@pid = Process.pid
|
@@ -32,15 +38,18 @@ module ActiveSupport
|
|
32
38
|
|
33
39
|
class << self
|
34
40
|
def check!
|
35
|
-
|
41
|
+
new_pid = Process.pid
|
42
|
+
if @pid != new_pid
|
36
43
|
@callbacks.each(&:call)
|
37
|
-
@pid =
|
44
|
+
@pid = new_pid
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
41
48
|
def hook!
|
42
|
-
if Process.respond_to?(:
|
43
|
-
::
|
49
|
+
if Process.respond_to?(:_fork) # Ruby 3.1+
|
50
|
+
::Process.singleton_class.prepend(ModernCoreExt)
|
51
|
+
elsif Process.respond_to?(:fork)
|
52
|
+
::Object.prepend(CoreExtPrivate) if RUBY_VERSION < "3.0"
|
44
53
|
::Kernel.prepend(CoreExtPrivate)
|
45
54
|
::Kernel.singleton_class.prepend(CoreExt)
|
46
55
|
::Process.singleton_class.prepend(CoreExt)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module HtmlSafeTranslation # :nodoc:
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def translate(key, **options)
|
8
|
+
if html_safe_translation_key?(key)
|
9
|
+
html_safe_options = html_escape_translation_options(options)
|
10
|
+
translation = I18n.translate(key, **html_safe_options)
|
11
|
+
html_safe_translation(translation)
|
12
|
+
else
|
13
|
+
I18n.translate(key, **options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def html_safe_translation_key?(key)
|
19
|
+
/(?:_|\b)html\z/.match?(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def html_escape_translation_options(options)
|
23
|
+
options.each do |name, value|
|
24
|
+
unless i18n_option?(name) || (name == :count && value.is_a?(Numeric))
|
25
|
+
options[name] = ERB::Util.html_escape(value.to_s)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def i18n_option?(name)
|
31
|
+
(@i18n_option_names ||= I18n::RESERVED_KEYS.to_set).include?(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def html_safe_translation(translation)
|
36
|
+
if translation.respond_to?(:map)
|
37
|
+
translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
|
38
|
+
else
|
39
|
+
translation.respond_to?(:html_safe) ? translation.html_safe : translation
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -77,7 +77,7 @@ module I18n
|
|
77
77
|
|
78
78
|
def self.forward_raise_on_missing_translations_config(app)
|
79
79
|
ActiveSupport.on_load(:action_view) do
|
80
|
-
|
80
|
+
ActionView::Helpers::TranslationHelper.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
|
81
81
|
end
|
82
82
|
|
83
83
|
ActiveSupport.on_load(:action_controller) do
|
@@ -222,15 +222,24 @@ module ActiveSupport
|
|
222
222
|
# Clears the loaded inflections within a given scope (default is
|
223
223
|
# <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
|
224
224
|
# options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
|
225
|
-
# <tt>:humans</tt>.
|
225
|
+
# <tt>:humans</tt>, <tt>:acronyms</tt>.
|
226
226
|
#
|
227
227
|
# clear :all
|
228
228
|
# clear :plurals
|
229
229
|
def clear(scope = :all)
|
230
230
|
case scope
|
231
231
|
when :all
|
232
|
-
|
233
|
-
|
232
|
+
clear(:acronyms)
|
233
|
+
clear(:plurals)
|
234
|
+
clear(:singulars)
|
235
|
+
clear(:uncountables)
|
236
|
+
clear(:humans)
|
237
|
+
when :acronyms
|
238
|
+
@acronyms = {}
|
239
|
+
define_acronym_regex_patterns
|
240
|
+
when :uncountables
|
241
|
+
@uncountables = Uncountables.new
|
242
|
+
when :plurals, :singulars, :humans
|
234
243
|
instance_variable_set "@#{scope}", []
|
235
244
|
end
|
236
245
|
end
|
@@ -97,7 +97,7 @@ module ActiveSupport
|
|
97
97
|
return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
|
98
98
|
word = camel_cased_word.to_s.gsub("::", "/")
|
99
99
|
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
|
100
|
-
word.gsub!(/([A-Z
|
100
|
+
word.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { ($1 || $2) << "_" }
|
101
101
|
word.tr!("-", "_")
|
102
102
|
word.downcase!
|
103
103
|
word
|
@@ -109,7 +109,7 @@ module ActiveSupport
|
|
109
109
|
#
|
110
110
|
# * Applies human inflection rules to the argument.
|
111
111
|
# * Deletes leading underscores, if any.
|
112
|
-
# * Removes
|
112
|
+
# * Removes an "_id" suffix if present.
|
113
113
|
# * Replaces underscores with spaces, if any.
|
114
114
|
# * Downcases all words except acronyms.
|
115
115
|
# * Capitalizes the first word.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fiber"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
module IsolatedExecutionState # :nodoc:
|
7
|
+
@isolation_level = :thread
|
8
|
+
|
9
|
+
Thread.attr_accessor :active_support_execution_state
|
10
|
+
Fiber.attr_accessor :active_support_execution_state
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :isolation_level
|
14
|
+
|
15
|
+
def isolation_level=(level)
|
16
|
+
unless %i(thread fiber).include?(level)
|
17
|
+
raise ArgumentError, "isolation_level must be `:thread` or `:fiber`, got: `#{level.inspect}`"
|
18
|
+
end
|
19
|
+
|
20
|
+
if level != isolation_level
|
21
|
+
clear
|
22
|
+
singleton_class.alias_method(:current, "current_#{level}")
|
23
|
+
singleton_class.send(:private, :current)
|
24
|
+
@isolation_level = level
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def unique_id
|
29
|
+
self[:__id__] ||= Object.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](key)
|
33
|
+
current[key]
|
34
|
+
end
|
35
|
+
|
36
|
+
def []=(key, value)
|
37
|
+
current[key] = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def clear
|
41
|
+
current.clear
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def current_thread
|
46
|
+
Thread.current.active_support_execution_state ||= {}
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_fiber
|
50
|
+
Fiber.current.active_support_execution_state ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_method :current, :current_thread
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -18,8 +18,7 @@ module ActiveSupport
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def local_level
|
21
|
-
|
22
|
-
Thread.current[:logger_thread_safe_level]
|
21
|
+
IsolatedExecutionState[:logger_thread_safe_level]
|
23
22
|
end
|
24
23
|
|
25
24
|
def local_level=(level)
|
@@ -31,7 +30,7 @@ module ActiveSupport
|
|
31
30
|
else
|
32
31
|
raise ArgumentError, "Invalid log level: #{level.inspect}"
|
33
32
|
end
|
34
|
-
|
33
|
+
IsolatedExecutionState[:logger_thread_safe_level] = level
|
35
34
|
end
|
36
35
|
|
37
36
|
def level
|
@@ -22,6 +22,11 @@ module ActiveSupport
|
|
22
22
|
# crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
|
23
23
|
# encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
|
24
24
|
# crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
|
25
|
+
# The +decrypt_and_verify+ method will raise an
|
26
|
+
# <tt>ActiveSupport::MessageEncryptor::InvalidMessage</tt> exception if the data
|
27
|
+
# provided cannot be decrypted or verified.
|
28
|
+
#
|
29
|
+
# crypt.decrypt_and_verify('not encrypted data') # => ActiveSupport::MessageEncryptor::InvalidMessage
|
25
30
|
#
|
26
31
|
# === Confining messages to a specific purpose
|
27
32
|
#
|
@@ -8,18 +8,6 @@ module ActiveSupport
|
|
8
8
|
# The Unicode version that is supported by the implementation
|
9
9
|
UNICODE_VERSION = RbConfig::CONFIG["UNICODE_VERSION"]
|
10
10
|
|
11
|
-
def default_normalization_form
|
12
|
-
ActiveSupport::Deprecation.warn(
|
13
|
-
"ActiveSupport::Multibyte::Unicode.default_normalization_form is deprecated and will be removed in Rails 7.0."
|
14
|
-
)
|
15
|
-
end
|
16
|
-
|
17
|
-
def default_normalization_form=(_)
|
18
|
-
ActiveSupport::Deprecation.warn(
|
19
|
-
"ActiveSupport::Multibyte::Unicode.default_normalization_form= is deprecated and will be removed in Rails 7.0."
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
11
|
# Decompose composed characters to the decomposed form.
|
24
12
|
def decompose(type, codepoints)
|
25
13
|
if type == :compatibility
|
@@ -7,6 +7,16 @@ require "active_support/core_ext/object/try"
|
|
7
7
|
|
8
8
|
module ActiveSupport
|
9
9
|
module Notifications
|
10
|
+
class InstrumentationSubscriberError < RuntimeError
|
11
|
+
attr_reader :exceptions
|
12
|
+
|
13
|
+
def initialize(exceptions)
|
14
|
+
@exceptions = exceptions
|
15
|
+
exception_class_names = exceptions.map { |e| e.class.name }
|
16
|
+
super "Exception(s) occurred within instrumentation subscribers: #{exception_class_names.join(', ')}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
10
20
|
# This is a default queue implementation that ships with Notifications.
|
11
21
|
# It just pushes events to all registered log subscribers.
|
12
22
|
#
|
@@ -59,19 +69,40 @@ module ActiveSupport
|
|
59
69
|
end
|
60
70
|
|
61
71
|
def start(name, id, payload)
|
62
|
-
listeners_for(name)
|
72
|
+
iterate_guarding_exceptions(listeners_for(name)) { |s| s.start(name, id, payload) }
|
63
73
|
end
|
64
74
|
|
65
75
|
def finish(name, id, payload, listeners = listeners_for(name))
|
66
|
-
listeners
|
76
|
+
iterate_guarding_exceptions(listeners) { |s| s.finish(name, id, payload) }
|
67
77
|
end
|
68
78
|
|
69
79
|
def publish(name, *args)
|
70
|
-
listeners_for(name)
|
80
|
+
iterate_guarding_exceptions(listeners_for(name)) { |s| s.publish(name, *args) }
|
71
81
|
end
|
72
82
|
|
73
83
|
def publish_event(event)
|
74
|
-
listeners_for(event.name)
|
84
|
+
iterate_guarding_exceptions(listeners_for(event.name)) { |s| s.publish_event(event) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def iterate_guarding_exceptions(listeners)
|
88
|
+
exceptions = nil
|
89
|
+
|
90
|
+
listeners.each do |s|
|
91
|
+
yield s
|
92
|
+
rescue Exception => e
|
93
|
+
exceptions ||= []
|
94
|
+
exceptions << e
|
95
|
+
end
|
96
|
+
|
97
|
+
if exceptions
|
98
|
+
if exceptions.size == 1
|
99
|
+
raise exceptions.first
|
100
|
+
else
|
101
|
+
raise InstrumentationSubscriberError.new(exceptions), cause: exceptions.first
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
listeners
|
75
106
|
end
|
76
107
|
|
77
108
|
def listeners_for(name)
|
@@ -108,23 +139,20 @@ module ActiveSupport
|
|
108
139
|
end
|
109
140
|
end
|
110
141
|
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.wrap_all(pattern, subscriber)
|
115
|
-
unless pattern
|
116
|
-
AllMessages.new(subscriber)
|
117
|
-
else
|
118
|
-
subscriber
|
119
|
-
end
|
142
|
+
subscriber_class.new(pattern, listener)
|
120
143
|
end
|
121
144
|
|
122
145
|
class Matcher # :nodoc:
|
123
146
|
attr_reader :pattern, :exclusions
|
124
147
|
|
125
148
|
def self.wrap(pattern)
|
126
|
-
|
127
|
-
|
149
|
+
if String === pattern
|
150
|
+
pattern
|
151
|
+
elsif pattern.nil?
|
152
|
+
AllMessages.new
|
153
|
+
else
|
154
|
+
new(pattern)
|
155
|
+
end
|
128
156
|
end
|
129
157
|
|
130
158
|
def initialize(pattern)
|
@@ -139,6 +167,16 @@ module ActiveSupport
|
|
139
167
|
def ===(name)
|
140
168
|
pattern === name && !exclusions.include?(name)
|
141
169
|
end
|
170
|
+
|
171
|
+
class AllMessages
|
172
|
+
def ===(name)
|
173
|
+
true
|
174
|
+
end
|
175
|
+
|
176
|
+
def unsubscribe!(*)
|
177
|
+
false
|
178
|
+
end
|
179
|
+
end
|
142
180
|
end
|
143
181
|
|
144
182
|
class Evented # :nodoc:
|
@@ -177,10 +215,6 @@ module ActiveSupport
|
|
177
215
|
pattern === name
|
178
216
|
end
|
179
217
|
|
180
|
-
def matches?(name)
|
181
|
-
pattern && pattern === name
|
182
|
-
end
|
183
|
-
|
184
218
|
def unsubscribe!(name)
|
185
219
|
pattern.unsubscribe!(name)
|
186
220
|
end
|
@@ -192,12 +226,12 @@ module ActiveSupport
|
|
192
226
|
end
|
193
227
|
|
194
228
|
def start(name, id, payload)
|
195
|
-
timestack =
|
229
|
+
timestack = IsolatedExecutionState[:_timestack] ||= []
|
196
230
|
timestack.push Time.now
|
197
231
|
end
|
198
232
|
|
199
233
|
def finish(name, id, payload)
|
200
|
-
timestack =
|
234
|
+
timestack = IsolatedExecutionState[:_timestack]
|
201
235
|
started = timestack.pop
|
202
236
|
@delegate.call(name, started, Time.now, id, payload)
|
203
237
|
end
|
@@ -209,27 +243,27 @@ module ActiveSupport
|
|
209
243
|
end
|
210
244
|
|
211
245
|
def start(name, id, payload)
|
212
|
-
timestack =
|
213
|
-
timestack.push
|
246
|
+
timestack = IsolatedExecutionState[:_timestack_monotonic] ||= []
|
247
|
+
timestack.push Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
214
248
|
end
|
215
249
|
|
216
250
|
def finish(name, id, payload)
|
217
|
-
timestack =
|
251
|
+
timestack = IsolatedExecutionState[:_timestack_monotonic]
|
218
252
|
started = timestack.pop
|
219
|
-
@delegate.call(name, started,
|
253
|
+
@delegate.call(name, started, Process.clock_gettime(Process::CLOCK_MONOTONIC), id, payload)
|
220
254
|
end
|
221
255
|
end
|
222
256
|
|
223
257
|
class EventObject < Evented
|
224
258
|
def start(name, id, payload)
|
225
|
-
stack =
|
259
|
+
stack = IsolatedExecutionState[:_event_stack] ||= []
|
226
260
|
event = build_event name, id, payload
|
227
261
|
event.start!
|
228
262
|
stack.push event
|
229
263
|
end
|
230
264
|
|
231
265
|
def finish(name, id, payload)
|
232
|
-
stack =
|
266
|
+
stack = IsolatedExecutionState[:_event_stack]
|
233
267
|
event = stack.pop
|
234
268
|
event.payload = payload
|
235
269
|
event.finish!
|
@@ -245,34 +279,6 @@ module ActiveSupport
|
|
245
279
|
ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
|
246
280
|
end
|
247
281
|
end
|
248
|
-
|
249
|
-
class AllMessages # :nodoc:
|
250
|
-
def initialize(delegate)
|
251
|
-
@delegate = delegate
|
252
|
-
end
|
253
|
-
|
254
|
-
def start(name, id, payload)
|
255
|
-
@delegate.start name, id, payload
|
256
|
-
end
|
257
|
-
|
258
|
-
def finish(name, id, payload)
|
259
|
-
@delegate.finish name, id, payload
|
260
|
-
end
|
261
|
-
|
262
|
-
def publish(name, *args)
|
263
|
-
@delegate.publish name, *args
|
264
|
-
end
|
265
|
-
|
266
|
-
def subscribed_to?(name)
|
267
|
-
true
|
268
|
-
end
|
269
|
-
|
270
|
-
def unsubscribe!(*)
|
271
|
-
false
|
272
|
-
end
|
273
|
-
|
274
|
-
alias :matches? :===
|
275
|
-
end
|
276
282
|
end
|
277
283
|
end
|
278
284
|
end
|
@@ -62,12 +62,12 @@ module ActiveSupport
|
|
62
62
|
def initialize(name, start, ending, transaction_id, payload)
|
63
63
|
@name = name
|
64
64
|
@payload = payload.dup
|
65
|
-
@time = start
|
65
|
+
@time = start ? start.to_f * 1_000.0 : start
|
66
66
|
@transaction_id = transaction_id
|
67
|
-
@end = ending
|
67
|
+
@end = ending ? ending.to_f * 1_000.0 : ending
|
68
68
|
@children = []
|
69
|
-
@cpu_time_start = 0
|
70
|
-
@cpu_time_finish = 0
|
69
|
+
@cpu_time_start = 0.0
|
70
|
+
@cpu_time_finish = 0.0
|
71
71
|
@allocation_count_start = 0
|
72
72
|
@allocation_count_finish = 0
|
73
73
|
end
|
@@ -102,7 +102,7 @@ module ActiveSupport
|
|
102
102
|
# Returns the CPU time (in milliseconds) passed since the call to
|
103
103
|
# +start!+ and the call to +finish!+
|
104
104
|
def cpu_time
|
105
|
-
|
105
|
+
@cpu_time_finish - @cpu_time_start
|
106
106
|
end
|
107
107
|
|
108
108
|
# Returns the idle time time (in milliseconds) passed since the call to
|
@@ -130,7 +130,7 @@ module ActiveSupport
|
|
130
130
|
#
|
131
131
|
# @event.duration # => 1000.138
|
132
132
|
def duration
|
133
|
-
|
133
|
+
self.end - time
|
134
134
|
end
|
135
135
|
|
136
136
|
def <<(event)
|
@@ -143,28 +143,28 @@ module ActiveSupport
|
|
143
143
|
|
144
144
|
private
|
145
145
|
def now
|
146
|
-
|
146
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
|
147
147
|
end
|
148
148
|
|
149
149
|
begin
|
150
|
-
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
|
150
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
151
151
|
|
152
152
|
def now_cpu
|
153
|
-
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
|
153
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
154
154
|
end
|
155
155
|
rescue
|
156
|
-
def now_cpu
|
157
|
-
0
|
156
|
+
def now_cpu # rubocop:disable Lint/DuplicateMethods
|
157
|
+
0.0
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
|
-
if
|
161
|
+
if GC.stat.key?(:total_allocated_objects)
|
162
162
|
def now_allocations
|
163
|
-
|
163
|
+
GC.stat(:total_allocated_objects)
|
164
164
|
end
|
165
|
-
else
|
165
|
+
else # Likely on JRuby, TruffleRuby
|
166
166
|
def now_allocations
|
167
|
-
|
167
|
+
0
|
168
168
|
end
|
169
169
|
end
|
170
170
|
end
|