activesupport 6.1.4.1 → 7.0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -395
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/backtrace_cleaner.rb +2 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +15 -9
- data/lib/active_support/cache/mem_cache_store.rb +148 -37
- data/lib/active_support/cache/memory_store.rb +24 -16
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +68 -85
- data/lib/active_support/cache/strategy/local_cache.rb +38 -61
- data/lib/active_support/cache.rb +299 -147
- data/lib/active_support/callbacks.rb +184 -85
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +5 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/configuration_file.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +13 -12
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +25 -17
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +14 -14
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +40 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +112 -38
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -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/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
- 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/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/json.rb +30 -25
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- 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/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +3 -26
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -5
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +94 -38
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +13 -8
- data/lib/active_support/core_ext/time/conversions.rb +13 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +73 -0
- data/lib/active_support/core_ext/time/zones.rb +10 -26
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -27
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/current_attributes.rb +31 -14
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +8 -5
- data/lib/active_support/deprecation/disallowed.rb +3 -3
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +174 -68
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -1
- data/lib/active_support/duration.rb +81 -51
- data/lib/active_support/encrypted_configuration.rb +45 -3
- data/lib/active_support/encrypted_file.rb +21 -10
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +20 -7
- 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 +43 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +19 -12
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +3 -1
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +23 -7
- data/lib/active_support/inflector/methods.rb +29 -55
- data/lib/active_support/inflector/transliterate.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +22 -5
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +15 -5
- data/lib/active_support/logger_thread_safe_level.rb +4 -13
- data/lib/active_support/message_encryptor.rb +12 -6
- data/lib/active_support/message_verifier.rb +46 -14
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +91 -65
- data/lib/active_support/notifications/instrumenter.rb +32 -15
- data/lib/active_support/notifications.rb +23 -23
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/rounding_helper.rb +1 -5
- data/lib/active_support/number_helper.rb +4 -5
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +20 -11
- data/lib/active_support/per_thread_registry.rb +5 -0
- data/lib/active_support/railtie.rb +69 -19
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +12 -12
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +2 -2
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +7 -18
- data/lib/active_support/tagged_logging.rb +2 -2
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +36 -6
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +13 -2
- data/lib/active_support/time_with_zone.rb +43 -22
- data/lib/active_support/values/time_zone.rb +35 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +17 -1
- metadata +26 -23
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -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
|
#
|
@@ -24,12 +34,15 @@ module ActiveSupport
|
|
24
34
|
def subscribe(pattern = nil, callable = nil, monotonic: false, &block)
|
25
35
|
subscriber = Subscribers.new(pattern, callable || block, monotonic)
|
26
36
|
synchronize do
|
27
|
-
|
37
|
+
case pattern
|
38
|
+
when String
|
28
39
|
@string_subscribers[pattern] << subscriber
|
29
40
|
@listeners_for.delete(pattern)
|
30
|
-
|
41
|
+
when NilClass, Regexp
|
31
42
|
@other_subscribers << subscriber
|
32
43
|
@listeners_for.clear
|
44
|
+
else
|
45
|
+
raise ArgumentError, "pattern must be specified as a String, Regexp or empty"
|
33
46
|
end
|
34
47
|
end
|
35
48
|
subscriber
|
@@ -56,15 +69,40 @@ module ActiveSupport
|
|
56
69
|
end
|
57
70
|
|
58
71
|
def start(name, id, payload)
|
59
|
-
listeners_for(name)
|
72
|
+
iterate_guarding_exceptions(listeners_for(name)) { |s| s.start(name, id, payload) }
|
60
73
|
end
|
61
74
|
|
62
75
|
def finish(name, id, payload, listeners = listeners_for(name))
|
63
|
-
listeners
|
76
|
+
iterate_guarding_exceptions(listeners) { |s| s.finish(name, id, payload) }
|
64
77
|
end
|
65
78
|
|
66
79
|
def publish(name, *args)
|
67
|
-
listeners_for(name)
|
80
|
+
iterate_guarding_exceptions(listeners_for(name)) { |s| s.publish(name, *args) }
|
81
|
+
end
|
82
|
+
|
83
|
+
def publish_event(event)
|
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
|
68
106
|
end
|
69
107
|
|
70
108
|
def listeners_for(name)
|
@@ -91,33 +129,30 @@ module ActiveSupport
|
|
91
129
|
if listener.respond_to?(:start) && listener.respond_to?(:finish)
|
92
130
|
subscriber_class = Evented
|
93
131
|
else
|
94
|
-
# Doing
|
95
|
-
# `proc {
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
132
|
+
# Doing this to detect a single argument block or callable
|
133
|
+
# like `proc { |x| }` vs `proc { |*x| }`, `proc { |**x| }`,
|
134
|
+
# or `proc { |x, **y| }`
|
135
|
+
procish = listener.respond_to?(:parameters) ? listener : listener.method(:call)
|
136
|
+
|
137
|
+
if procish.arity == 1 && procish.parameters.length == 1
|
138
|
+
subscriber_class = EventObject
|
101
139
|
end
|
102
140
|
end
|
103
141
|
|
104
|
-
|
105
|
-
end
|
106
|
-
|
107
|
-
def self.wrap_all(pattern, subscriber)
|
108
|
-
unless pattern
|
109
|
-
AllMessages.new(subscriber)
|
110
|
-
else
|
111
|
-
subscriber
|
112
|
-
end
|
142
|
+
subscriber_class.new(pattern, listener)
|
113
143
|
end
|
114
144
|
|
115
|
-
class Matcher
|
145
|
+
class Matcher # :nodoc:
|
116
146
|
attr_reader :pattern, :exclusions
|
117
147
|
|
118
148
|
def self.wrap(pattern)
|
119
|
-
|
120
|
-
|
149
|
+
if String === pattern
|
150
|
+
pattern
|
151
|
+
elsif pattern.nil?
|
152
|
+
AllMessages.new
|
153
|
+
else
|
154
|
+
new(pattern)
|
155
|
+
end
|
121
156
|
end
|
122
157
|
|
123
158
|
def initialize(pattern)
|
@@ -132,15 +167,26 @@ module ActiveSupport
|
|
132
167
|
def ===(name)
|
133
168
|
pattern === name && !exclusions.include?(name)
|
134
169
|
end
|
170
|
+
|
171
|
+
class AllMessages
|
172
|
+
def ===(name)
|
173
|
+
true
|
174
|
+
end
|
175
|
+
|
176
|
+
def unsubscribe!(*)
|
177
|
+
false
|
178
|
+
end
|
179
|
+
end
|
135
180
|
end
|
136
181
|
|
137
|
-
class Evented
|
182
|
+
class Evented # :nodoc:
|
138
183
|
attr_reader :pattern
|
139
184
|
|
140
185
|
def initialize(pattern, delegate)
|
141
186
|
@pattern = Matcher.wrap(pattern)
|
142
187
|
@delegate = delegate
|
143
188
|
@can_publish = delegate.respond_to?(:publish)
|
189
|
+
@can_publish_event = delegate.respond_to?(:publish_event)
|
144
190
|
end
|
145
191
|
|
146
192
|
def publish(name, *args)
|
@@ -149,6 +195,14 @@ module ActiveSupport
|
|
149
195
|
end
|
150
196
|
end
|
151
197
|
|
198
|
+
def publish_event(event)
|
199
|
+
if @can_publish_event
|
200
|
+
@delegate.publish_event event
|
201
|
+
else
|
202
|
+
publish(event.name, event.time, event.end, event.transaction_id, event.payload)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
152
206
|
def start(name, id, payload)
|
153
207
|
@delegate.start name, id, payload
|
154
208
|
end
|
@@ -161,10 +215,6 @@ module ActiveSupport
|
|
161
215
|
pattern === name
|
162
216
|
end
|
163
217
|
|
164
|
-
def matches?(name)
|
165
|
-
pattern && pattern === name
|
166
|
-
end
|
167
|
-
|
168
218
|
def unsubscribe!(name)
|
169
219
|
pattern.unsubscribe!(name)
|
170
220
|
end
|
@@ -176,12 +226,12 @@ module ActiveSupport
|
|
176
226
|
end
|
177
227
|
|
178
228
|
def start(name, id, payload)
|
179
|
-
timestack =
|
229
|
+
timestack = IsolatedExecutionState[:_timestack] ||= []
|
180
230
|
timestack.push Time.now
|
181
231
|
end
|
182
232
|
|
183
233
|
def finish(name, id, payload)
|
184
|
-
timestack =
|
234
|
+
timestack = IsolatedExecutionState[:_timestack]
|
185
235
|
started = timestack.pop
|
186
236
|
@delegate.call(name, started, Time.now, id, payload)
|
187
237
|
end
|
@@ -193,66 +243,42 @@ module ActiveSupport
|
|
193
243
|
end
|
194
244
|
|
195
245
|
def start(name, id, payload)
|
196
|
-
timestack =
|
197
|
-
timestack.push
|
246
|
+
timestack = IsolatedExecutionState[:_timestack_monotonic] ||= []
|
247
|
+
timestack.push Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
198
248
|
end
|
199
249
|
|
200
250
|
def finish(name, id, payload)
|
201
|
-
timestack =
|
251
|
+
timestack = IsolatedExecutionState[:_timestack_monotonic]
|
202
252
|
started = timestack.pop
|
203
|
-
@delegate.call(name, started,
|
253
|
+
@delegate.call(name, started, Process.clock_gettime(Process::CLOCK_MONOTONIC), id, payload)
|
204
254
|
end
|
205
255
|
end
|
206
256
|
|
207
257
|
class EventObject < Evented
|
208
258
|
def start(name, id, payload)
|
209
|
-
stack =
|
259
|
+
stack = IsolatedExecutionState[:_event_stack] ||= []
|
210
260
|
event = build_event name, id, payload
|
211
261
|
event.start!
|
212
262
|
stack.push event
|
213
263
|
end
|
214
264
|
|
215
265
|
def finish(name, id, payload)
|
216
|
-
stack =
|
266
|
+
stack = IsolatedExecutionState[:_event_stack]
|
217
267
|
event = stack.pop
|
218
268
|
event.payload = payload
|
219
269
|
event.finish!
|
220
270
|
@delegate.call event
|
221
271
|
end
|
222
272
|
|
273
|
+
def publish_event(event)
|
274
|
+
@delegate.call event
|
275
|
+
end
|
276
|
+
|
223
277
|
private
|
224
278
|
def build_event(name, id, payload)
|
225
279
|
ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
|
226
280
|
end
|
227
281
|
end
|
228
|
-
|
229
|
-
class AllMessages # :nodoc:
|
230
|
-
def initialize(delegate)
|
231
|
-
@delegate = delegate
|
232
|
-
end
|
233
|
-
|
234
|
-
def start(name, id, payload)
|
235
|
-
@delegate.start name, id, payload
|
236
|
-
end
|
237
|
-
|
238
|
-
def finish(name, id, payload)
|
239
|
-
@delegate.finish name, id, payload
|
240
|
-
end
|
241
|
-
|
242
|
-
def publish(name, *args)
|
243
|
-
@delegate.publish name, *args
|
244
|
-
end
|
245
|
-
|
246
|
-
def subscribed_to?(name)
|
247
|
-
true
|
248
|
-
end
|
249
|
-
|
250
|
-
def unsubscribe!(*)
|
251
|
-
false
|
252
|
-
end
|
253
|
-
|
254
|
-
alias :matches? :===
|
255
|
-
end
|
256
282
|
end
|
257
283
|
end
|
258
284
|
end
|
@@ -31,6 +31,10 @@ module ActiveSupport
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
def new_event(name, payload = {}) # :nodoc:
|
35
|
+
Event.new(name, nil, nil, @id, payload)
|
36
|
+
end
|
37
|
+
|
34
38
|
# Send a start notification with +name+ and +payload+.
|
35
39
|
def start(name, payload)
|
36
40
|
@notifier.start name, @id, payload
|
@@ -58,16 +62,29 @@ module ActiveSupport
|
|
58
62
|
def initialize(name, start, ending, transaction_id, payload)
|
59
63
|
@name = name
|
60
64
|
@payload = payload.dup
|
61
|
-
@time = start
|
65
|
+
@time = start ? start.to_f * 1_000.0 : start
|
62
66
|
@transaction_id = transaction_id
|
63
|
-
@end = ending
|
67
|
+
@end = ending ? ending.to_f * 1_000.0 : ending
|
64
68
|
@children = []
|
65
|
-
@cpu_time_start = 0
|
66
|
-
@cpu_time_finish = 0
|
69
|
+
@cpu_time_start = 0.0
|
70
|
+
@cpu_time_finish = 0.0
|
67
71
|
@allocation_count_start = 0
|
68
72
|
@allocation_count_finish = 0
|
69
73
|
end
|
70
74
|
|
75
|
+
def record
|
76
|
+
start!
|
77
|
+
begin
|
78
|
+
yield payload if block_given?
|
79
|
+
rescue Exception => e
|
80
|
+
payload[:exception] = [e.class.name, e.message]
|
81
|
+
payload[:exception_object] = e
|
82
|
+
raise e
|
83
|
+
ensure
|
84
|
+
finish!
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
71
88
|
# Record information at the time this event starts
|
72
89
|
def start!
|
73
90
|
@time = now
|
@@ -85,7 +102,7 @@ module ActiveSupport
|
|
85
102
|
# Returns the CPU time (in milliseconds) passed since the call to
|
86
103
|
# +start!+ and the call to +finish!+
|
87
104
|
def cpu_time
|
88
|
-
|
105
|
+
@cpu_time_finish - @cpu_time_start
|
89
106
|
end
|
90
107
|
|
91
108
|
# Returns the idle time time (in milliseconds) passed since the call to
|
@@ -113,7 +130,7 @@ module ActiveSupport
|
|
113
130
|
#
|
114
131
|
# @event.duration # => 1000.138
|
115
132
|
def duration
|
116
|
-
|
133
|
+
self.end - time
|
117
134
|
end
|
118
135
|
|
119
136
|
def <<(event)
|
@@ -126,28 +143,28 @@ module ActiveSupport
|
|
126
143
|
|
127
144
|
private
|
128
145
|
def now
|
129
|
-
|
146
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
|
130
147
|
end
|
131
148
|
|
132
149
|
begin
|
133
|
-
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
|
150
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
134
151
|
|
135
152
|
def now_cpu
|
136
|
-
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
|
153
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
137
154
|
end
|
138
155
|
rescue
|
139
|
-
def now_cpu
|
140
|
-
0
|
156
|
+
def now_cpu # rubocop:disable Lint/DuplicateMethods
|
157
|
+
0.0
|
141
158
|
end
|
142
159
|
end
|
143
160
|
|
144
|
-
if
|
161
|
+
if GC.stat.key?(:total_allocated_objects)
|
145
162
|
def now_allocations
|
146
|
-
|
163
|
+
GC.stat(:total_allocated_objects)
|
147
164
|
end
|
148
|
-
else
|
165
|
+
else # Likely on JRuby, TruffleRuby
|
149
166
|
def now_allocations
|
150
|
-
|
167
|
+
0
|
151
168
|
end
|
152
169
|
end
|
153
170
|
end
|
@@ -2,10 +2,9 @@
|
|
2
2
|
|
3
3
|
require "active_support/notifications/instrumenter"
|
4
4
|
require "active_support/notifications/fanout"
|
5
|
-
require "active_support/per_thread_registry"
|
6
5
|
|
7
6
|
module ActiveSupport
|
8
|
-
# = Notifications
|
7
|
+
# = \Notifications
|
9
8
|
#
|
10
9
|
# <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
|
11
10
|
# Ruby.
|
@@ -85,7 +84,7 @@ module ActiveSupport
|
|
85
84
|
# event.payload[:exception] # => ["ArgumentError", "Invalid value"]
|
86
85
|
# event.payload[:exception_object] # => #<ArgumentError: Invalid value>
|
87
86
|
#
|
88
|
-
# As the earlier example depicts, the class
|
87
|
+
# As the earlier example depicts, the class ActiveSupport::Notifications::Event
|
89
88
|
# is able to take the arguments as they come and provide an object-oriented
|
90
89
|
# interface to that data.
|
91
90
|
#
|
@@ -198,6 +197,10 @@ module ActiveSupport
|
|
198
197
|
notifier.publish(name, *args)
|
199
198
|
end
|
200
199
|
|
200
|
+
def publish_event(event) # :nodoc:
|
201
|
+
notifier.publish_event(event)
|
202
|
+
end
|
203
|
+
|
201
204
|
def instrument(name, payload = {})
|
202
205
|
if notifier.listening?(name)
|
203
206
|
instrumenter.instrument(name, payload) { yield payload if block_given? }
|
@@ -231,10 +234,22 @@ module ActiveSupport
|
|
231
234
|
# ActiveSupport::Notifications.subscribe(/render/) do |event|
|
232
235
|
# @event = event
|
233
236
|
# end
|
237
|
+
#
|
238
|
+
# Raises an error if invalid event name type is passed:
|
239
|
+
#
|
240
|
+
# ActiveSupport::Notifications.subscribe(:render) {|*args| ...}
|
241
|
+
# #=> ArgumentError (pattern must be specified as a String, Regexp or empty)
|
242
|
+
#
|
234
243
|
def subscribe(pattern = nil, callback = nil, &block)
|
235
244
|
notifier.subscribe(pattern, callback, monotonic: false, &block)
|
236
245
|
end
|
237
246
|
|
247
|
+
# Performs the same functionality as #subscribe, but the +start+ and
|
248
|
+
# +finish+ block arguments are in monotonic time instead of wall-clock
|
249
|
+
# time. Monotonic time will not jump forward or backward (due to NTP or
|
250
|
+
# Daylights Savings). Use +monotonic_subscribe+ when accuracy of time
|
251
|
+
# duration is important. For example, computing elapsed time between
|
252
|
+
# two events.
|
238
253
|
def monotonic_subscribe(pattern = nil, callback = nil, &block)
|
239
254
|
notifier.subscribe(pattern, callback, monotonic: true, &block)
|
240
255
|
end
|
@@ -251,28 +266,13 @@ module ActiveSupport
|
|
251
266
|
end
|
252
267
|
|
253
268
|
def instrumenter
|
254
|
-
|
269
|
+
registry[notifier] ||= Instrumenter.new(notifier)
|
255
270
|
end
|
256
|
-
end
|
257
271
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
# InstrumentationRegistry.instrumenter_for(notifier)
|
263
|
-
#
|
264
|
-
# The instrumenters for multiple notifiers are held in a single instance of
|
265
|
-
# this class.
|
266
|
-
class InstrumentationRegistry # :nodoc:
|
267
|
-
extend ActiveSupport::PerThreadRegistry
|
268
|
-
|
269
|
-
def initialize
|
270
|
-
@registry = {}
|
271
|
-
end
|
272
|
-
|
273
|
-
def instrumenter_for(notifier)
|
274
|
-
@registry[notifier] ||= Instrumenter.new(notifier)
|
275
|
-
end
|
272
|
+
private
|
273
|
+
def registry
|
274
|
+
ActiveSupport::IsolatedExecutionState[:active_support_notifications_registry] ||= {}
|
275
|
+
end
|
276
276
|
end
|
277
277
|
|
278
278
|
self.notifier = Fanout.new
|
@@ -8,16 +8,21 @@ module ActiveSupport
|
|
8
8
|
self.namespace = :currency
|
9
9
|
|
10
10
|
def convert
|
11
|
-
number = self.number.to_s.strip
|
12
11
|
format = options[:format]
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
number_f = valid_float?
|
14
|
+
if number_f
|
15
|
+
if number_f.negative?
|
16
|
+
number_f = number_f.abs
|
17
|
+
format = options[:negative_format] if (number_f * 10**options[:precision]) >= 0.5
|
18
|
+
end
|
19
|
+
number_s = NumberToRoundedConverter.convert(number_f, options)
|
20
|
+
else
|
21
|
+
number_s = number.to_s.strip
|
22
|
+
format = options[:negative_format] if number_s.sub!(/^-/, "")
|
17
23
|
end
|
18
24
|
|
19
|
-
|
20
|
-
format.gsub("%n", rounded_number).gsub("%u", options[:unit])
|
25
|
+
format.gsub("%n", number_s).gsub("%u", options[:unit])
|
21
26
|
end
|
22
27
|
|
23
28
|
private
|
@@ -4,7 +4,7 @@ require "active_support/number_helper/number_converter"
|
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
module NumberHelper
|
7
|
-
class NumberToDelimitedConverter < NumberConverter
|
7
|
+
class NumberToDelimitedConverter < NumberConverter # :nodoc:
|
8
8
|
self.validate_float = true
|
9
9
|
|
10
10
|
DEFAULT_DELIMITER_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
|
@@ -4,7 +4,7 @@ require "active_support/number_helper/number_converter"
|
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
module NumberHelper
|
7
|
-
class NumberToHumanSizeConverter < NumberConverter
|
7
|
+
class NumberToHumanSizeConverter < NumberConverter # :nodoc:
|
8
8
|
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb]
|
9
9
|
|
10
10
|
self.namespace = :human
|
@@ -4,7 +4,7 @@ require "active_support/number_helper/number_converter"
|
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
module NumberHelper
|
7
|
-
class NumberToPhoneConverter < NumberConverter
|
7
|
+
class NumberToPhoneConverter < NumberConverter # :nodoc:
|
8
8
|
def convert
|
9
9
|
str = country_code(opts[:country_code]).dup
|
10
10
|
str << convert_to_phone_number(number.to_s.strip)
|
@@ -35,16 +35,12 @@ module ActiveSupport
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def absolute_precision(number)
|
38
|
-
if significant && options[:precision] > 0
|
38
|
+
if options[:significant] && options[:precision] > 0
|
39
39
|
options[:precision] - digit_count(convert_to_decimal(number))
|
40
40
|
else
|
41
41
|
options[:precision]
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
45
|
-
def significant
|
46
|
-
options[:significant]
|
47
|
-
end
|
48
44
|
end
|
49
45
|
end
|
50
46
|
end
|
@@ -99,8 +99,6 @@ module ActiveSupport
|
|
99
99
|
# number_to_currency(1234567890.506, locale: :fr) # => "1 234 567 890,51 €"
|
100
100
|
# number_to_currency('123a456') # => "$123a456"
|
101
101
|
#
|
102
|
-
# number_to_currency("123a456", raise: true) # => InvalidNumberError
|
103
|
-
#
|
104
102
|
# number_to_currency(-0.456789, precision: 0)
|
105
103
|
# # => "$0"
|
106
104
|
# number_to_currency(-1234567890.50, negative_format: '(%u%n)')
|
@@ -360,13 +358,14 @@ module ActiveSupport
|
|
360
358
|
# out by default (set <tt>:strip_insignificant_zeros</tt> to
|
361
359
|
# +false+ to change that):
|
362
360
|
#
|
363
|
-
#
|
364
|
-
#
|
361
|
+
# number_to_human(12.00001) # => "12"
|
362
|
+
# number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
|
365
363
|
#
|
366
364
|
# ==== Custom Unit Quantifiers
|
367
365
|
#
|
368
366
|
# You can also use your own custom unit quantifiers:
|
369
|
-
#
|
367
|
+
#
|
368
|
+
# number_to_human(500000, units: { unit: 'ml', thousand: 'lt' }) # => "500 lt"
|
370
369
|
#
|
371
370
|
# If in your I18n locale you have:
|
372
371
|
#
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/hash/deep_merge"
|
4
|
-
require "active_support/core_ext/symbol/starts_ends_with"
|
5
4
|
|
6
5
|
module ActiveSupport
|
7
|
-
class OptionMerger
|
6
|
+
class OptionMerger # :nodoc:
|
8
7
|
instance_methods.each do |method|
|
9
8
|
undef_method(method) unless method.start_with?("__", "instance_eval", "class", "object_id")
|
10
9
|
end
|
@@ -16,8 +15,8 @@ module ActiveSupport
|
|
16
15
|
private
|
17
16
|
def method_missing(method, *arguments, &block)
|
18
17
|
options = nil
|
19
|
-
if arguments.first.is_a?(Proc)
|
20
|
-
proc = arguments.
|
18
|
+
if arguments.size == 1 && arguments.first.is_a?(Proc)
|
19
|
+
proc = arguments.shift
|
21
20
|
arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
|
22
21
|
elsif arguments.last.respond_to?(:to_hash)
|
23
22
|
options = @options.deep_merge(arguments.pop)
|
@@ -25,22 +24,15 @@ module ActiveSupport
|
|
25
24
|
options = @options
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if RUBY_VERSION >= "2.7"
|
32
|
-
def invoke_method(method, arguments, options, &block)
|
33
|
-
if options
|
34
|
-
@context.__send__(method, *arguments, **options, &block)
|
35
|
-
else
|
36
|
-
@context.__send__(method, *arguments, &block)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
else
|
40
|
-
def invoke_method(method, arguments, options, &block)
|
41
|
-
arguments << options.dup if options
|
27
|
+
if options
|
28
|
+
@context.__send__(method, *arguments, **options, &block)
|
29
|
+
else
|
42
30
|
@context.__send__(method, *arguments, &block)
|
43
31
|
end
|
44
32
|
end
|
33
|
+
|
34
|
+
def respond_to_missing?(*arguments)
|
35
|
+
@context.respond_to?(*arguments)
|
36
|
+
end
|
45
37
|
end
|
46
38
|
end
|
@@ -21,7 +21,7 @@ module ActiveSupport
|
|
21
21
|
#
|
22
22
|
# <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
|
23
23
|
# with other implementations.
|
24
|
-
class OrderedHash < ::Hash
|
24
|
+
class OrderedHash < ::Hash # :nodoc:
|
25
25
|
def to_yaml_type
|
26
26
|
"!tag:yaml.org,2002:omap"
|
27
27
|
end
|
@@ -68,7 +68,7 @@ module ActiveSupport
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
# +InheritableOptions+ provides a constructor to build an
|
71
|
+
# +InheritableOptions+ provides a constructor to build an OrderedOptions
|
72
72
|
# hash inherited from another hash.
|
73
73
|
#
|
74
74
|
# Use this if you already have some hash and you want to create a new one based on it.
|