activesupport 6.0.6.1 → 7.1.3.2
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 +865 -438
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -6
- data/lib/active_support/actionable_error.rb +4 -2
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +30 -10
- data/lib/active_support/benchmarkable.rb +4 -3
- data/lib/active_support/broadcast_logger.rb +250 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +53 -20
- data/lib/active_support/cache/mem_cache_store.rb +208 -63
- data/lib/active_support/cache/memory_store.rb +120 -38
- data/lib/active_support/cache/null_store.rb +16 -2
- data/lib/active_support/cache/redis_cache_store.rb +201 -208
- data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -66
- data/lib/active_support/cache.rb +539 -261
- data/lib/active_support/callbacks.rb +273 -142
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +53 -7
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +19 -6
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +15 -13
- 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/benchmark.rb +2 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +19 -29
- 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 +18 -16
- data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- 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 +19 -15
- data/lib/active_support/core_ext/digest/uuid.rb +30 -13
- data/lib/active_support/core_ext/enumerable.rb +146 -72
- data/lib/active_support/core_ext/erb/util.rb +196 -0
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +3 -4
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +4 -4
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +5 -5
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- 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/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +31 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +51 -20
- data/lib/active_support/core_ext/module/concerning.rb +14 -8
- data/lib/active_support/core_ext/module/delegation.rb +75 -42
- data/lib/active_support/core_ext/module/deprecation.rb +15 -12
- data/lib/active_support/core_ext/module/introspection.rb +1 -26
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +82 -73
- 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 +17 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
- data/lib/active_support/core_ext/object/json.rb +52 -28
- 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.rb +44 -0
- data/lib/active_support/core_ext/object/with_options.rb +25 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +16 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +6 -25
- data/lib/active_support/core_ext/range/conversions.rb +34 -13
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/regexp.rb +8 -1
- data/lib/active_support/core_ext/securerandom.rb +25 -13
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +21 -15
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +51 -10
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +85 -194
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +46 -8
- data/lib/active_support/core_ext/time/conversions.rb +16 -13
- data/lib/active_support/core_ext/time/zones.rb +12 -28
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +54 -22
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/dependencies/autoload.rb +17 -12
- 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 -769
- data/lib/active_support/deprecation/behaviors.rb +77 -38
- data/lib/active_support/deprecation/constant_accessor.rb +5 -4
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +54 -0
- data/lib/active_support/deprecation/instance_delegator.rb +31 -5
- data/lib/active_support/deprecation/method_wrappers.rb +12 -28
- data/lib/active_support/deprecation/proxy_wrappers.rb +40 -25
- data/lib/active_support/deprecation/reporting.rb +76 -16
- data/lib/active_support/deprecation.rb +36 -4
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +150 -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 +24 -12
- data/lib/active_support/duration.rb +136 -56
- data/lib/active_support/encrypted_configuration.rb +72 -9
- data/lib/active_support/encrypted_file.rb +46 -13
- data/lib/active_support/environment_inquirer.rb +40 -0
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +203 -0
- data/lib/active_support/evented_file_update_checker.rb +86 -137
- 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 +31 -12
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +4 -2
- data/lib/active_support/fork_tracker.rb +79 -0
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +86 -42
- data/lib/active_support/html_safe_translation.rb +53 -0
- data/lib/active_support/i18n.rb +2 -1
- data/lib/active_support/i18n_railtie.rb +29 -27
- data/lib/active_support/inflector/inflections.rb +26 -9
- data/lib/active_support/inflector/methods.rb +54 -64
- data/lib/active_support/inflector/transliterate.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +6 -5
- data/lib/active_support/json/encoding.rb +31 -45
- data/lib/active_support/key_generator.rb +32 -7
- data/lib/active_support/lazy_load_hooks.rb +33 -7
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +101 -32
- data/lib/active_support/logger.rb +9 -60
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +24 -25
- data/lib/active_support/message_encryptor.rb +205 -58
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +292 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +237 -86
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +112 -46
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +35 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +15 -52
- data/lib/active_support/multibyte/unicode.rb +8 -122
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +310 -105
- data/lib/active_support/notifications/instrumenter.rb +113 -48
- data/lib/active_support/notifications.rb +56 -29
- data/lib/active_support/number_helper/number_converter.rb +15 -8
- 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_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -5
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +379 -304
- data/lib/active_support/option_merger.rb +11 -18
- data/lib/active_support/ordered_hash.rb +4 -4
- data/lib/active_support/ordered_options.rb +23 -3
- data/lib/active_support/parameter_filter.rb +104 -75
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +90 -6
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +18 -16
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +58 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +5 -3
- data/lib/active_support/subscriber.rb +23 -47
- data/lib/active_support/syntax_error_proxy.rb +70 -0
- data/lib/active_support/tagged_logging.rb +84 -23
- data/lib/active_support/test_case.rb +166 -27
- data/lib/active_support/testing/assertions.rb +73 -20
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +32 -0
- data/lib/active_support/testing/deprecation.rb +53 -2
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +24 -11
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +16 -95
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/stream.rb +4 -6
- data/lib/active_support/testing/strict_warnings.rb +39 -0
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +89 -19
- data/lib/active_support/time_with_zone.rb +105 -70
- data/lib/active_support/values/time_zone.rb +59 -26
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +4 -11
- 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 +5 -5
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +9 -2
- data/lib/active_support/xml_mini.rb +7 -6
- data/lib/active_support.rb +40 -1
- metadata +127 -40
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -23
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/uri.rb +0 -25
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
- data/lib/active_support/per_thread_registry.rb +0 -60
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/module/delegation"
|
3
4
|
require "securerandom"
|
4
5
|
|
5
6
|
module ActiveSupport
|
@@ -9,17 +10,50 @@ module ActiveSupport
|
|
9
10
|
attr_reader :id
|
10
11
|
|
11
12
|
def initialize(notifier)
|
13
|
+
unless notifier.respond_to?(:build_handle)
|
14
|
+
notifier = LegacyHandle::Wrapper.new(notifier)
|
15
|
+
end
|
16
|
+
|
12
17
|
@id = unique_id
|
13
18
|
@notifier = notifier
|
14
19
|
end
|
15
20
|
|
21
|
+
class LegacyHandle # :nodoc:
|
22
|
+
class Wrapper # :nodoc:
|
23
|
+
def initialize(notifier)
|
24
|
+
@notifier = notifier
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_handle(name, id, payload)
|
28
|
+
LegacyHandle.new(@notifier, name, id, payload)
|
29
|
+
end
|
30
|
+
|
31
|
+
delegate :start, :finish, to: :@notifier
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(notifier, name, id, payload)
|
35
|
+
@notifier = notifier
|
36
|
+
@name = name
|
37
|
+
@id = id
|
38
|
+
@payload = payload
|
39
|
+
end
|
40
|
+
|
41
|
+
def start
|
42
|
+
@listener_state = @notifier.start @name, @id, @payload
|
43
|
+
end
|
44
|
+
|
45
|
+
def finish
|
46
|
+
@notifier.finish(@name, @id, @payload, @listener_state)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
16
50
|
# Given a block, instrument it by measuring the time taken to execute
|
17
51
|
# and publish it. Without a block, simply send a message via the
|
18
52
|
# notifier. Notice that events get sent even if an error occurs in the
|
19
53
|
# passed-in block.
|
20
54
|
def instrument(name, payload = {})
|
21
|
-
|
22
|
-
|
55
|
+
handle = build_handle(name, payload)
|
56
|
+
handle.start
|
23
57
|
begin
|
24
58
|
yield payload if block_given?
|
25
59
|
rescue Exception => e
|
@@ -27,10 +61,28 @@ module ActiveSupport
|
|
27
61
|
payload[:exception_object] = e
|
28
62
|
raise e
|
29
63
|
ensure
|
30
|
-
|
64
|
+
handle.finish
|
31
65
|
end
|
32
66
|
end
|
33
67
|
|
68
|
+
# Returns a "handle" for an event with the given +name+ and +payload+.
|
69
|
+
#
|
70
|
+
# #start and #finish must each be called exactly once on the returned object.
|
71
|
+
#
|
72
|
+
# Where possible, it's best to use #instrument, which will record the
|
73
|
+
# start and finish of the event and correctly handle any exceptions.
|
74
|
+
# +build_handle+ is a low-level API intended for cases where using
|
75
|
+
# +instrument+ isn't possible.
|
76
|
+
#
|
77
|
+
# See ActiveSupport::Notifications::Fanout::Handle.
|
78
|
+
def build_handle(name, payload)
|
79
|
+
@notifier.build_handle(name, @id, payload)
|
80
|
+
end
|
81
|
+
|
82
|
+
def new_event(name, payload = {}) # :nodoc:
|
83
|
+
Event.new(name, nil, nil, @id, payload)
|
84
|
+
end
|
85
|
+
|
34
86
|
# Send a start notification with +name+ and +payload+.
|
35
87
|
def start(name, payload)
|
36
88
|
@notifier.start name, @id, payload
|
@@ -52,28 +104,34 @@ module ActiveSupport
|
|
52
104
|
end
|
53
105
|
|
54
106
|
class Event
|
55
|
-
attr_reader :name, :time, :end, :transaction_id
|
56
|
-
|
57
|
-
def self.clock_gettime_supported? # :nodoc:
|
58
|
-
defined?(Process::CLOCK_THREAD_CPUTIME_ID) &&
|
59
|
-
!Gem.win_platform? &&
|
60
|
-
!RUBY_PLATFORM.match?(/solaris/i)
|
61
|
-
end
|
62
|
-
private_class_method :clock_gettime_supported?
|
107
|
+
attr_reader :name, :time, :end, :transaction_id
|
108
|
+
attr_accessor :payload
|
63
109
|
|
64
110
|
def initialize(name, start, ending, transaction_id, payload)
|
65
111
|
@name = name
|
66
112
|
@payload = payload.dup
|
67
|
-
@time = start
|
113
|
+
@time = start ? start.to_f * 1_000.0 : start
|
68
114
|
@transaction_id = transaction_id
|
69
|
-
@end = ending
|
70
|
-
@
|
71
|
-
@
|
72
|
-
@cpu_time_finish = 0
|
115
|
+
@end = ending ? ending.to_f * 1_000.0 : ending
|
116
|
+
@cpu_time_start = 0.0
|
117
|
+
@cpu_time_finish = 0.0
|
73
118
|
@allocation_count_start = 0
|
74
119
|
@allocation_count_finish = 0
|
75
120
|
end
|
76
121
|
|
122
|
+
def record
|
123
|
+
start!
|
124
|
+
begin
|
125
|
+
yield payload if block_given?
|
126
|
+
rescue Exception => e
|
127
|
+
payload[:exception] = [e.class.name, e.message]
|
128
|
+
payload[:exception_object] = e
|
129
|
+
raise e
|
130
|
+
ensure
|
131
|
+
finish!
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
77
135
|
# Record information at the time this event starts
|
78
136
|
def start!
|
79
137
|
@time = now
|
@@ -88,29 +146,42 @@ module ActiveSupport
|
|
88
146
|
@allocation_count_finish = now_allocations
|
89
147
|
end
|
90
148
|
|
91
|
-
|
92
|
-
|
93
|
-
@end = ending
|
94
|
-
end
|
95
|
-
|
96
|
-
# Returns the CPU time (in milliseconds) passed since the call to
|
97
|
-
# +start!+ and the call to +finish!+
|
149
|
+
# Returns the CPU time (in milliseconds) passed between the call to
|
150
|
+
# #start! and the call to #finish!.
|
98
151
|
def cpu_time
|
99
|
-
|
152
|
+
@cpu_time_finish - @cpu_time_start
|
100
153
|
end
|
101
154
|
|
102
|
-
# Returns the idle time time (in milliseconds) passed
|
103
|
-
#
|
155
|
+
# Returns the idle time time (in milliseconds) passed between the call to
|
156
|
+
# #start! and the call to #finish!.
|
104
157
|
def idle_time
|
105
|
-
duration - cpu_time
|
158
|
+
diff = duration - cpu_time
|
159
|
+
diff > 0.0 ? diff : 0.0
|
106
160
|
end
|
107
161
|
|
108
|
-
# Returns the number of allocations made
|
109
|
-
# the call to
|
162
|
+
# Returns the number of allocations made between the call to #start! and
|
163
|
+
# the call to #finish!.
|
110
164
|
def allocations
|
111
165
|
@allocation_count_finish - @allocation_count_start
|
112
166
|
end
|
113
167
|
|
168
|
+
def children # :nodoc:
|
169
|
+
ActiveSupport.deprecator.warn <<~EOM
|
170
|
+
ActiveSupport::Notifications::Event#children is deprecated and will
|
171
|
+
be removed in Rails 7.2.
|
172
|
+
EOM
|
173
|
+
[]
|
174
|
+
end
|
175
|
+
|
176
|
+
def parent_of?(event) # :nodoc:
|
177
|
+
ActiveSupport.deprecator.warn <<~EOM
|
178
|
+
ActiveSupport::Notifications::Event#parent_of? is deprecated and will
|
179
|
+
be removed in Rails 7.2.
|
180
|
+
EOM
|
181
|
+
start = (time - event.time) * 1000
|
182
|
+
start <= 0 && (start + duration >= event.duration)
|
183
|
+
end
|
184
|
+
|
114
185
|
# Returns the difference in milliseconds between when the execution of the
|
115
186
|
# event started and when it ended.
|
116
187
|
#
|
@@ -124,39 +195,33 @@ module ActiveSupport
|
|
124
195
|
#
|
125
196
|
# @event.duration # => 1000.138
|
126
197
|
def duration
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
def <<(event)
|
131
|
-
@children << event
|
132
|
-
end
|
133
|
-
|
134
|
-
def parent_of?(event)
|
135
|
-
@children.include? event
|
198
|
+
self.end - time
|
136
199
|
end
|
137
200
|
|
138
201
|
private
|
139
202
|
def now
|
140
|
-
|
203
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
|
141
204
|
end
|
142
205
|
|
143
|
-
|
206
|
+
begin
|
207
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
208
|
+
|
144
209
|
def now_cpu
|
145
|
-
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
|
210
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
146
211
|
end
|
147
|
-
|
148
|
-
def now_cpu
|
149
|
-
0
|
212
|
+
rescue
|
213
|
+
def now_cpu # rubocop:disable Lint/DuplicateMethods
|
214
|
+
0.0
|
150
215
|
end
|
151
216
|
end
|
152
217
|
|
153
|
-
if
|
218
|
+
if GC.stat.key?(:total_allocated_objects)
|
154
219
|
def now_allocations
|
155
|
-
|
220
|
+
GC.stat(:total_allocated_objects)
|
156
221
|
end
|
157
|
-
else
|
222
|
+
else # Likely on JRuby, TruffleRuby
|
158
223
|
def now_allocations
|
159
|
-
|
224
|
+
0
|
160
225
|
end
|
161
226
|
end
|
162
227
|
end
|
@@ -2,12 +2,11 @@
|
|
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
|
+
# +ActiveSupport::Notifications+ provides an instrumentation API for
|
11
10
|
# Ruby.
|
12
11
|
#
|
13
12
|
# == Instrumenters
|
@@ -38,6 +37,19 @@ module ActiveSupport
|
|
38
37
|
# payload # => Hash, the payload
|
39
38
|
# end
|
40
39
|
#
|
40
|
+
# Here, the +start+ and +finish+ values represent wall-clock time. If you are
|
41
|
+
# concerned about accuracy, you can register a monotonic subscriber.
|
42
|
+
#
|
43
|
+
# ActiveSupport::Notifications.monotonic_subscribe('render') do |name, start, finish, id, payload|
|
44
|
+
# name # => String, name of the event (such as 'render' from above)
|
45
|
+
# start # => Monotonic time, when the instrumented block started execution
|
46
|
+
# finish # => Monotonic time, when the instrumented block ended execution
|
47
|
+
# id # => String, unique ID for the instrumenter that fired the event
|
48
|
+
# payload # => Hash, the payload
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# The +start+ and +finish+ values above represent monotonic time.
|
52
|
+
#
|
41
53
|
# For instance, let's store all "render" events in an array:
|
42
54
|
#
|
43
55
|
# events = []
|
@@ -72,7 +84,7 @@ module ActiveSupport
|
|
72
84
|
# event.payload[:exception] # => ["ArgumentError", "Invalid value"]
|
73
85
|
# event.payload[:exception_object] # => #<ArgumentError: Invalid value>
|
74
86
|
#
|
75
|
-
# As the earlier example depicts, the class
|
87
|
+
# As the earlier example depicts, the class ActiveSupport::Notifications::Event
|
76
88
|
# is able to take the arguments as they come and provide an object-oriented
|
77
89
|
# interface to that data.
|
78
90
|
#
|
@@ -135,6 +147,16 @@ module ActiveSupport
|
|
135
147
|
# during the execution of the block. The callback is unsubscribed automatically
|
136
148
|
# after that.
|
137
149
|
#
|
150
|
+
# To record +started+ and +finished+ values with monotonic time,
|
151
|
+
# specify the optional <tt>:monotonic</tt> option to the
|
152
|
+
# <tt>subscribed</tt> method. The <tt>:monotonic</tt> option is set
|
153
|
+
# to +false+ by default.
|
154
|
+
#
|
155
|
+
# callback = lambda {|name, started, finished, unique_id, payload| ... }
|
156
|
+
# ActiveSupport::Notifications.subscribed(callback, "sql.active_record", monotonic: true) do
|
157
|
+
# ...
|
158
|
+
# end
|
159
|
+
#
|
138
160
|
# === Manual Unsubscription
|
139
161
|
#
|
140
162
|
# The +subscribe+ method returns a subscriber object:
|
@@ -155,7 +177,7 @@ module ActiveSupport
|
|
155
177
|
#
|
156
178
|
# Subscribers using a regexp or other pattern-matching object will remain subscribed
|
157
179
|
# to all events that match their original pattern, unless those events match a string
|
158
|
-
# passed to
|
180
|
+
# passed to +unsubscribe+:
|
159
181
|
#
|
160
182
|
# subscriber = ActiveSupport::Notifications.subscribe(/render/) { }
|
161
183
|
# ActiveSupport::Notifications.unsubscribe('render_template.action_view')
|
@@ -175,6 +197,10 @@ module ActiveSupport
|
|
175
197
|
notifier.publish(name, *args)
|
176
198
|
end
|
177
199
|
|
200
|
+
def publish_event(event) # :nodoc:
|
201
|
+
notifier.publish_event(event)
|
202
|
+
end
|
203
|
+
|
178
204
|
def instrument(name, payload = {})
|
179
205
|
if notifier.listening?(name)
|
180
206
|
instrumenter.instrument(name, payload) { yield payload if block_given? }
|
@@ -208,12 +234,28 @@ module ActiveSupport
|
|
208
234
|
# ActiveSupport::Notifications.subscribe(/render/) do |event|
|
209
235
|
# @event = event
|
210
236
|
# end
|
211
|
-
|
212
|
-
|
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
|
+
#
|
243
|
+
def subscribe(pattern = nil, callback = nil, &block)
|
244
|
+
notifier.subscribe(pattern, callback, monotonic: false, &block)
|
245
|
+
end
|
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.
|
253
|
+
def monotonic_subscribe(pattern = nil, callback = nil, &block)
|
254
|
+
notifier.subscribe(pattern, callback, monotonic: true, &block)
|
213
255
|
end
|
214
256
|
|
215
|
-
def subscribed(callback,
|
216
|
-
subscriber = subscribe(
|
257
|
+
def subscribed(callback, pattern = nil, monotonic: false, &block)
|
258
|
+
subscriber = notifier.subscribe(pattern, callback, monotonic: monotonic)
|
217
259
|
yield
|
218
260
|
ensure
|
219
261
|
unsubscribe(subscriber)
|
@@ -224,28 +266,13 @@ module ActiveSupport
|
|
224
266
|
end
|
225
267
|
|
226
268
|
def instrumenter
|
227
|
-
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
# This class is a registry which holds all of the +Instrumenter+ objects
|
232
|
-
# in a particular thread local. To access the +Instrumenter+ object for a
|
233
|
-
# particular +notifier+, you can call the following method:
|
234
|
-
#
|
235
|
-
# InstrumentationRegistry.instrumenter_for(notifier)
|
236
|
-
#
|
237
|
-
# The instrumenters for multiple notifiers are held in a single instance of
|
238
|
-
# this class.
|
239
|
-
class InstrumentationRegistry # :nodoc:
|
240
|
-
extend ActiveSupport::PerThreadRegistry
|
241
|
-
|
242
|
-
def initialize
|
243
|
-
@registry = {}
|
269
|
+
registry[notifier] ||= Instrumenter.new(notifier)
|
244
270
|
end
|
245
271
|
|
246
|
-
|
247
|
-
|
248
|
-
|
272
|
+
private
|
273
|
+
def registry
|
274
|
+
ActiveSupport::IsolatedExecutionState[:active_support_notifications_registry] ||= {}
|
275
|
+
end
|
249
276
|
end
|
250
277
|
|
251
278
|
self.notifier = Fanout.new
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "bigdecimal"
|
4
|
+
require "bigdecimal/util"
|
3
5
|
require "active_support/core_ext/big_decimal/conversions"
|
4
|
-
require "active_support/core_ext/object/blank"
|
5
6
|
require "active_support/core_ext/hash/keys"
|
6
7
|
require "active_support/i18n"
|
7
8
|
require "active_support/core_ext/class/attribute"
|
@@ -30,7 +31,7 @@ module ActiveSupport
|
|
30
31
|
# If set to true, precision will mean the number of significant digits instead
|
31
32
|
# of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
|
32
33
|
significant: false,
|
33
|
-
# If set, the zeros after the decimal separator will always be stripped (
|
34
|
+
# If set, the zeros after the decimal separator will always be stripped (e.g.: 1.200 will be 1.2)
|
34
35
|
strip_insignificant_zeros: false
|
35
36
|
},
|
36
37
|
|
@@ -122,13 +123,14 @@ module ActiveSupport
|
|
122
123
|
|
123
124
|
def initialize(number, options)
|
124
125
|
@number = number
|
125
|
-
@opts
|
126
|
+
@opts = options.symbolize_keys
|
127
|
+
@options = nil
|
126
128
|
end
|
127
129
|
|
128
130
|
def execute
|
129
131
|
if !number
|
130
132
|
nil
|
131
|
-
elsif validate_float? && !
|
133
|
+
elsif validate_float? && !valid_bigdecimal
|
132
134
|
number
|
133
135
|
else
|
134
136
|
convert
|
@@ -173,10 +175,15 @@ module ActiveSupport
|
|
173
175
|
key.split(".").reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }
|
174
176
|
end
|
175
177
|
|
176
|
-
def
|
177
|
-
|
178
|
-
|
179
|
-
|
178
|
+
def valid_bigdecimal
|
179
|
+
case number
|
180
|
+
when Float, Rational
|
181
|
+
number.to_d(0)
|
182
|
+
when String
|
183
|
+
BigDecimal(number, exception: false)
|
184
|
+
else
|
185
|
+
number.to_d rescue nil
|
186
|
+
end
|
180
187
|
end
|
181
188
|
end
|
182
189
|
end
|
@@ -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_d = valid_bigdecimal
|
14
|
+
if number_d
|
15
|
+
if number_d.negative?
|
16
|
+
number_d = number_d.abs
|
17
|
+
format = options[:negative_format] if (number_d * 10**options[:precision]) >= 0.5
|
18
|
+
end
|
19
|
+
number_s = NumberToRoundedConverter.convert(number_d, 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))/
|
@@ -16,7 +16,7 @@ module ActiveSupport
|
|
16
16
|
@number = RoundingHelper.new(options).round(number)
|
17
17
|
@number = Float(number)
|
18
18
|
|
19
|
-
#
|
19
|
+
# For backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files.
|
20
20
|
unless options.key?(:strip_insignificant_zeros)
|
21
21
|
options[:strip_insignificant_zeros] = true
|
22
22
|
end
|
@@ -4,8 +4,8 @@ require "active_support/number_helper/number_converter"
|
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
module NumberHelper
|
7
|
-
class NumberToHumanSizeConverter < NumberConverter
|
8
|
-
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb]
|
7
|
+
class NumberToHumanSizeConverter < NumberConverter # :nodoc:
|
8
|
+
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb, :zb]
|
9
9
|
|
10
10
|
self.namespace = :human
|
11
11
|
self.validate_float = true
|
@@ -13,7 +13,7 @@ module ActiveSupport
|
|
13
13
|
def convert
|
14
14
|
@number = Float(number)
|
15
15
|
|
16
|
-
#
|
16
|
+
# For backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files.
|
17
17
|
unless options.key?(:strip_insignificant_zeros)
|
18
18
|
options[:strip_insignificant_zeros] = true
|
19
19
|
end
|
@@ -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
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/object/blank"
|
3
4
|
require "active_support/number_helper/number_converter"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
module NumberHelper
|
7
|
-
class NumberToPhoneConverter < NumberConverter
|
8
|
+
class NumberToPhoneConverter < NumberConverter # :nodoc:
|
8
9
|
def convert
|
9
10
|
str = country_code(opts[:country_code]).dup
|
10
11
|
str << convert_to_phone_number(number.to_s.strip)
|
@@ -20,14 +20,18 @@ module ActiveSupport
|
|
20
20
|
end
|
21
21
|
|
22
22
|
formatted_string =
|
23
|
-
if
|
23
|
+
if rounded_number.finite?
|
24
24
|
s = rounded_number.to_s("F")
|
25
|
-
s << "0" * precision
|
26
25
|
a, b = s.split(".", 2)
|
27
|
-
|
28
|
-
|
26
|
+
if precision != 0
|
27
|
+
b << "0" * precision
|
28
|
+
a << "."
|
29
|
+
a << b[0, precision]
|
30
|
+
end
|
31
|
+
a
|
29
32
|
else
|
30
|
-
|
33
|
+
# Infinity/NaN
|
34
|
+
"%f" % rounded_number
|
31
35
|
end
|
32
36
|
else
|
33
37
|
formatted_string = rounded_number
|
@@ -10,56 +10,36 @@ module ActiveSupport
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def round(number)
|
13
|
+
precision = absolute_precision(number)
|
13
14
|
return number unless precision
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
else
|
18
|
-
round_without_significant(number)
|
19
|
-
end
|
15
|
+
|
16
|
+
rounded_number = convert_to_decimal(number).round(precision, options.fetch(:round_mode, :default).to_sym)
|
17
|
+
rounded_number.zero? ? rounded_number.abs : rounded_number # prevent showing negative zeros
|
20
18
|
end
|
21
19
|
|
22
20
|
def digit_count(number)
|
23
21
|
return 1 if number.zero?
|
24
|
-
(Math.log10(
|
22
|
+
(Math.log10(number.abs) + 1).floor
|
25
23
|
end
|
26
24
|
|
27
25
|
private
|
28
|
-
def round_without_significant(number)
|
29
|
-
number = number.round(precision, BigDecimal.mode(BigDecimal::ROUND_MODE))
|
30
|
-
number = number.to_i if precision == 0 && number.finite?
|
31
|
-
number = number.abs if number.zero? # prevent showing negative zeros
|
32
|
-
number
|
33
|
-
end
|
34
|
-
|
35
|
-
def round_significant(number)
|
36
|
-
return 0 if number.zero?
|
37
|
-
digits = digit_count(number)
|
38
|
-
multiplier = 10**(digits - precision)
|
39
|
-
(number / BigDecimal(multiplier.to_f.to_s)).round * multiplier
|
40
|
-
end
|
41
|
-
|
42
26
|
def convert_to_decimal(number)
|
43
27
|
case number
|
44
28
|
when Float, String
|
45
29
|
BigDecimal(number.to_s)
|
46
30
|
when Rational
|
47
|
-
BigDecimal(number, digit_count(number.to_i) + precision)
|
31
|
+
BigDecimal(number, digit_count(number.to_i) + options[:precision])
|
48
32
|
else
|
49
33
|
number.to_d
|
50
34
|
end
|
51
35
|
end
|
52
36
|
|
53
|
-
def
|
54
|
-
options[:precision]
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
def absolute_number(number)
|
62
|
-
number.respond_to?(:abs) ? number.abs : number.to_d.abs
|
37
|
+
def absolute_precision(number)
|
38
|
+
if options[:significant] && options[:precision] > 0
|
39
|
+
options[:precision] - digit_count(convert_to_decimal(number))
|
40
|
+
else
|
41
|
+
options[:precision]
|
42
|
+
end
|
63
43
|
end
|
64
44
|
end
|
65
45
|
end
|