activesupport 4.0.12 → 7.0.2.4
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 +5 -5
- data/CHANGELOG.md +249 -501
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +41 -13
- data/lib/active_support/benchmarkable.rb +7 -15
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +96 -74
- data/lib/active_support/cache/mem_cache_store.rb +211 -103
- data/lib/active_support/cache/memory_store.rb +90 -58
- data/lib/active_support/cache/null_store.rb +19 -7
- data/lib/active_support/cache/redis_cache_store.rb +468 -0
- data/lib/active_support/cache/strategy/local_cache.rb +86 -83
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +580 -241
- data/lib/active_support/callbacks.rb +812 -425
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +103 -14
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +21 -19
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +47 -1
- data/lib/active_support/core_ext/array/conversions.rb +35 -44
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +26 -16
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +10 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
- data/lib/active_support/core_ext/class/subclasses.rb +25 -26
- data/lib/active_support/core_ext/class.rb +4 -4
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +31 -18
- data/lib/active_support/core_ext/date/conversions.rb +43 -32
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +5 -34
- data/lib/active_support/core_ext/date.rb +7 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +8 -4
- data/lib/active_support/core_ext/digest/uuid.rb +79 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +249 -17
- data/lib/active_support/core_ext/file/atomic.rb +41 -32
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +71 -49
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +14 -5
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +39 -56
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -23
- data/lib/active_support/core_ext/hash.rb +10 -8
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +5 -21
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
- data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +172 -45
- data/lib/active_support/core_ext/module/deprecation.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +23 -38
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -10
- data/lib/active_support/core_ext/name_error.rb +45 -4
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +37 -50
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +70 -20
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
- data/lib/active_support/core_ext/object/duplicable.rb +17 -47
- data/lib/active_support/core_ext/object/inclusion.rb +18 -15
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +244 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +21 -8
- data/lib/active_support/core_ext/object/try.rb +106 -26
- data/lib/active_support/core_ext/object/with_options.rb +64 -5
- data/lib/active_support/core_ext/object.rb +14 -12
- 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 +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +10 -1
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +42 -51
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +18 -13
- data/lib/active_support/core_ext/string/exclude.rb +5 -3
- data/lib/active_support/core_ext/string/filters.rb +97 -7
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +106 -25
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +18 -9
- data/lib/active_support/core_ext/string/output_safety.rb +227 -54
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -1
- data/lib/active_support/core_ext/string.rb +15 -13
- 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/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +178 -116
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +37 -25
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +44 -42
- data/lib/active_support/core_ext/time.rb +8 -5
- data/lib/active_support/core_ext/uri.rb +4 -25
- data/lib/active_support/core_ext.rb +4 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +3 -1
- data/lib/active_support/dependencies/interlock.rb +49 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +71 -696
- data/lib/active_support/deprecation/behaviors.rb +65 -16
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +62 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
- data/lib/active_support/deprecation/reporting.rb +81 -18
- data/lib/active_support/deprecation.rb +19 -11
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +67 -0
- data/lib/active_support/duration.rb +437 -39
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +170 -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 +151 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +207 -54
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +10 -6
- data/lib/active_support/i18n_railtie.rb +48 -19
- data/lib/active_support/inflections.rb +19 -12
- data/lib/active_support/inflector/inflections.rb +97 -37
- data/lib/active_support/inflector/methods.rb +192 -157
- data/lib/active_support/inflector/transliterate.rb +83 -33
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +64 -0
- data/lib/active_support/json/decoding.rb +37 -42
- data/lib/active_support/json/encoding.rb +93 -293
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +30 -47
- data/lib/active_support/lazy_load_hooks.rb +54 -21
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +61 -18
- data/lib/active_support/logger.rb +40 -4
- data/lib/active_support/logger_silence.rb +17 -20
- data/lib/active_support/logger_thread_safe_level.rb +69 -0
- data/lib/active_support/message_encryptor.rb +178 -55
- data/lib/active_support/message_verifier.rb +195 -26
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +45 -92
- data/lib/active_support/multibyte/unicode.rb +44 -377
- data/lib/active_support/multibyte.rb +5 -3
- data/lib/active_support/notifications/fanout.rb +177 -44
- data/lib/active_support/notifications/instrumenter.rb +117 -17
- data/lib/active_support/notifications.rb +106 -39
- data/lib/active_support/number_helper/number_converter.rb +181 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +152 -394
- data/lib/active_support/option_merger.rb +18 -5
- data/lib/active_support/ordered_hash.rb +8 -6
- data/lib/active_support/ordered_options.rb +43 -7
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +24 -11
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -11
- data/lib/active_support/railtie.rb +118 -12
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +112 -57
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +38 -0
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +109 -39
- data/lib/active_support/tagged_logging.rb +54 -17
- data/lib/active_support/test_case.rb +121 -37
- data/lib/active_support/testing/assertions.rb +177 -39
- data/lib/active_support/testing/autorun.rb +5 -3
- data/lib/active_support/testing/constant_lookup.rb +3 -6
- data/lib/active_support/testing/declarative.rb +10 -22
- data/lib/active_support/testing/deprecation.rb +65 -11
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +56 -87
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- 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 +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/setup_and_teardown.rb +30 -10
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +6 -4
- data/lib/active_support/testing/time_helpers.rb +246 -0
- data/lib/active_support/time.rb +13 -13
- data/lib/active_support/time_with_zone.rb +315 -90
- data/lib/active_support/values/time_zone.rb +306 -135
- data/lib/active_support/version.rb +6 -7
- data/lib/active_support/xml_mini/jdom.rb +117 -115
- data/lib/active_support/xml_mini/libxml.rb +22 -21
- data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
- data/lib/active_support/xml_mini/nokogiri.rb +19 -19
- data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
- data/lib/active_support/xml_mini/rexml.rb +25 -17
- data/lib/active_support/xml_mini.rb +67 -56
- data/lib/active_support.rb +58 -3
- metadata +125 -66
- data/lib/active_support/basic_object.rb +0 -11
- data/lib/active_support/buffered_logger.rb +0 -21
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
- data/lib/active_support/core_ext/date_time/zones.rb +0 -24
- data/lib/active_support/core_ext/hash/diff.rb +0 -14
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/logger.rb +0 -67
- data/lib/active_support/core_ext/marshal.rb +0 -21
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/object/to_json.rb +0 -27
- data/lib/active_support/core_ext/proc.rb +0 -17
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/core_ext/string/encoding.rb +0 -8
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -79
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -18
- data/lib/active_support/testing/pending.rb +0 -14
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,8 +1,22 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mutex_m"
|
4
|
+
require "concurrent/map"
|
5
|
+
require "set"
|
6
|
+
require "active_support/core_ext/object/try"
|
3
7
|
|
4
8
|
module ActiveSupport
|
5
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
|
+
|
6
20
|
# This is a default queue implementation that ships with Notifications.
|
7
21
|
# It just pushes events to all registered log subscribers.
|
8
22
|
#
|
@@ -11,44 +25,92 @@ module ActiveSupport
|
|
11
25
|
include Mutex_m
|
12
26
|
|
13
27
|
def initialize
|
14
|
-
@
|
15
|
-
@
|
28
|
+
@string_subscribers = Hash.new { |h, k| h[k] = [] }
|
29
|
+
@other_subscribers = []
|
30
|
+
@listeners_for = Concurrent::Map.new
|
16
31
|
super
|
17
32
|
end
|
18
33
|
|
19
|
-
def subscribe(pattern = nil,
|
20
|
-
subscriber = Subscribers.new
|
34
|
+
def subscribe(pattern = nil, callable = nil, monotonic: false, &block)
|
35
|
+
subscriber = Subscribers.new(pattern, callable || block, monotonic)
|
21
36
|
synchronize do
|
22
|
-
|
23
|
-
|
37
|
+
case pattern
|
38
|
+
when String
|
39
|
+
@string_subscribers[pattern] << subscriber
|
40
|
+
@listeners_for.delete(pattern)
|
41
|
+
when NilClass, Regexp
|
42
|
+
@other_subscribers << subscriber
|
43
|
+
@listeners_for.clear
|
44
|
+
else
|
45
|
+
raise ArgumentError, "pattern must be specified as a String, Regexp or empty"
|
46
|
+
end
|
24
47
|
end
|
25
48
|
subscriber
|
26
49
|
end
|
27
50
|
|
28
|
-
def unsubscribe(
|
51
|
+
def unsubscribe(subscriber_or_name)
|
29
52
|
synchronize do
|
30
|
-
|
31
|
-
|
53
|
+
case subscriber_or_name
|
54
|
+
when String
|
55
|
+
@string_subscribers[subscriber_or_name].clear
|
56
|
+
@listeners_for.delete(subscriber_or_name)
|
57
|
+
@other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) }
|
58
|
+
else
|
59
|
+
pattern = subscriber_or_name.try(:pattern)
|
60
|
+
if String === pattern
|
61
|
+
@string_subscribers[pattern].delete(subscriber_or_name)
|
62
|
+
@listeners_for.delete(pattern)
|
63
|
+
else
|
64
|
+
@other_subscribers.delete(subscriber_or_name)
|
65
|
+
@listeners_for.clear
|
66
|
+
end
|
67
|
+
end
|
32
68
|
end
|
33
69
|
end
|
34
70
|
|
35
71
|
def start(name, id, payload)
|
36
|
-
listeners_for(name)
|
72
|
+
iterate_guarding_exceptions(listeners_for(name)) { |s| s.start(name, id, payload) }
|
37
73
|
end
|
38
74
|
|
39
|
-
def finish(name, id, payload)
|
40
|
-
|
75
|
+
def finish(name, id, payload, listeners = listeners_for(name))
|
76
|
+
iterate_guarding_exceptions(listeners) { |s| s.finish(name, id, payload) }
|
41
77
|
end
|
42
78
|
|
43
79
|
def publish(name, *args)
|
44
|
-
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
|
45
106
|
end
|
46
107
|
|
47
108
|
def listeners_for(name)
|
48
|
-
# this is correctly done double-checked locking (
|
109
|
+
# this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
|
49
110
|
@listeners_for[name] || synchronize do
|
50
111
|
# use synchronisation when accessing @subscribers
|
51
|
-
@listeners_for[name] ||=
|
112
|
+
@listeners_for[name] ||=
|
113
|
+
@string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) }
|
52
114
|
end
|
53
115
|
end
|
54
116
|
|
@@ -61,25 +123,70 @@ module ActiveSupport
|
|
61
123
|
end
|
62
124
|
|
63
125
|
module Subscribers # :nodoc:
|
64
|
-
def self.new(pattern, listener)
|
65
|
-
|
66
|
-
|
126
|
+
def self.new(pattern, listener, monotonic)
|
127
|
+
subscriber_class = monotonic ? MonotonicTimed : Timed
|
128
|
+
|
129
|
+
if listener.respond_to?(:start) && listener.respond_to?(:finish)
|
130
|
+
subscriber_class = Evented
|
67
131
|
else
|
68
|
-
|
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
|
139
|
+
end
|
69
140
|
end
|
70
141
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
142
|
+
subscriber_class.new(pattern, listener)
|
143
|
+
end
|
144
|
+
|
145
|
+
class Matcher # :nodoc:
|
146
|
+
attr_reader :pattern, :exclusions
|
147
|
+
|
148
|
+
def self.wrap(pattern)
|
149
|
+
if String === pattern
|
150
|
+
pattern
|
151
|
+
elsif pattern.nil?
|
152
|
+
AllMessages.new
|
153
|
+
else
|
154
|
+
new(pattern)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def initialize(pattern)
|
159
|
+
@pattern = pattern
|
160
|
+
@exclusions = Set.new
|
161
|
+
end
|
162
|
+
|
163
|
+
def unsubscribe!(name)
|
164
|
+
exclusions << -name if pattern === name
|
165
|
+
end
|
166
|
+
|
167
|
+
def ===(name)
|
168
|
+
pattern === name && !exclusions.include?(name)
|
169
|
+
end
|
170
|
+
|
171
|
+
class AllMessages
|
172
|
+
def ===(name)
|
173
|
+
true
|
174
|
+
end
|
175
|
+
|
176
|
+
def unsubscribe!(*)
|
177
|
+
false
|
178
|
+
end
|
75
179
|
end
|
76
180
|
end
|
77
181
|
|
78
|
-
class Evented
|
182
|
+
class Evented # :nodoc:
|
183
|
+
attr_reader :pattern
|
184
|
+
|
79
185
|
def initialize(pattern, delegate)
|
80
|
-
@pattern = pattern
|
186
|
+
@pattern = Matcher.wrap(pattern)
|
81
187
|
@delegate = delegate
|
82
188
|
@can_publish = delegate.respond_to?(:publish)
|
189
|
+
@can_publish_event = delegate.respond_to?(:publish_event)
|
83
190
|
end
|
84
191
|
|
85
192
|
def publish(name, *args)
|
@@ -88,6 +195,14 @@ module ActiveSupport
|
|
88
195
|
end
|
89
196
|
end
|
90
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
|
+
|
91
206
|
def start(name, id, payload)
|
92
207
|
@delegate.start name, id, payload
|
93
208
|
end
|
@@ -97,54 +212,72 @@ module ActiveSupport
|
|
97
212
|
end
|
98
213
|
|
99
214
|
def subscribed_to?(name)
|
100
|
-
|
215
|
+
pattern === name
|
101
216
|
end
|
102
217
|
|
103
|
-
def
|
104
|
-
|
105
|
-
@pattern && @pattern === subscriber_or_name
|
218
|
+
def unsubscribe!(name)
|
219
|
+
pattern.unsubscribe!(name)
|
106
220
|
end
|
107
221
|
end
|
108
222
|
|
109
|
-
class Timed < Evented
|
223
|
+
class Timed < Evented # :nodoc:
|
110
224
|
def publish(name, *args)
|
111
225
|
@delegate.call name, *args
|
112
226
|
end
|
113
227
|
|
114
228
|
def start(name, id, payload)
|
115
|
-
timestack =
|
229
|
+
timestack = IsolatedExecutionState[:_timestack] ||= []
|
116
230
|
timestack.push Time.now
|
117
231
|
end
|
118
232
|
|
119
233
|
def finish(name, id, payload)
|
120
|
-
timestack =
|
234
|
+
timestack = IsolatedExecutionState[:_timestack]
|
121
235
|
started = timestack.pop
|
122
236
|
@delegate.call(name, started, Time.now, id, payload)
|
123
237
|
end
|
124
238
|
end
|
125
239
|
|
126
|
-
class
|
127
|
-
def
|
128
|
-
@delegate
|
240
|
+
class MonotonicTimed < Evented # :nodoc:
|
241
|
+
def publish(name, *args)
|
242
|
+
@delegate.call name, *args
|
129
243
|
end
|
130
244
|
|
131
245
|
def start(name, id, payload)
|
132
|
-
|
246
|
+
timestack = IsolatedExecutionState[:_timestack_monotonic] ||= []
|
247
|
+
timestack.push Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
133
248
|
end
|
134
249
|
|
135
250
|
def finish(name, id, payload)
|
136
|
-
|
251
|
+
timestack = IsolatedExecutionState[:_timestack_monotonic]
|
252
|
+
started = timestack.pop
|
253
|
+
@delegate.call(name, started, Process.clock_gettime(Process::CLOCK_MONOTONIC), id, payload)
|
137
254
|
end
|
255
|
+
end
|
138
256
|
|
139
|
-
|
140
|
-
|
257
|
+
class EventObject < Evented
|
258
|
+
def start(name, id, payload)
|
259
|
+
stack = IsolatedExecutionState[:_event_stack] ||= []
|
260
|
+
event = build_event name, id, payload
|
261
|
+
event.start!
|
262
|
+
stack.push event
|
141
263
|
end
|
142
264
|
|
143
|
-
def
|
144
|
-
|
265
|
+
def finish(name, id, payload)
|
266
|
+
stack = IsolatedExecutionState[:_event_stack]
|
267
|
+
event = stack.pop
|
268
|
+
event.payload = payload
|
269
|
+
event.finish!
|
270
|
+
@delegate.call event
|
145
271
|
end
|
146
272
|
|
147
|
-
|
273
|
+
def publish_event(event)
|
274
|
+
@delegate.call event
|
275
|
+
end
|
276
|
+
|
277
|
+
private
|
278
|
+
def build_event(name, id, payload)
|
279
|
+
ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
|
280
|
+
end
|
148
281
|
end
|
149
282
|
end
|
150
283
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
2
4
|
|
3
5
|
module ActiveSupport
|
4
6
|
module Notifications
|
@@ -11,21 +13,28 @@ module ActiveSupport
|
|
11
13
|
@notifier = notifier
|
12
14
|
end
|
13
15
|
|
14
|
-
#
|
15
|
-
# and publish it.
|
16
|
-
#
|
17
|
-
|
18
|
-
|
16
|
+
# Given a block, instrument it by measuring the time taken to execute
|
17
|
+
# and publish it. Without a block, simply send a message via the
|
18
|
+
# notifier. Notice that events get sent even if an error occurs in the
|
19
|
+
# passed-in block.
|
20
|
+
def instrument(name, payload = {})
|
21
|
+
# some of the listeners might have state
|
22
|
+
listeners_state = start name, payload
|
19
23
|
begin
|
20
|
-
yield payload
|
24
|
+
yield payload if block_given?
|
21
25
|
rescue Exception => e
|
22
26
|
payload[:exception] = [e.class.name, e.message]
|
27
|
+
payload[:exception_object] = e
|
23
28
|
raise e
|
24
29
|
ensure
|
25
|
-
|
30
|
+
finish_with_state listeners_state, name, payload
|
26
31
|
end
|
27
32
|
end
|
28
33
|
|
34
|
+
def new_event(name, payload = {}) # :nodoc:
|
35
|
+
Event.new(name, nil, nil, @id, payload)
|
36
|
+
end
|
37
|
+
|
29
38
|
# Send a start notification with +name+ and +payload+.
|
30
39
|
def start(name, payload)
|
31
40
|
@notifier.start name, @id, payload
|
@@ -36,28 +45,92 @@ module ActiveSupport
|
|
36
45
|
@notifier.finish name, @id, payload
|
37
46
|
end
|
38
47
|
|
39
|
-
|
40
|
-
|
41
|
-
def unique_id
|
42
|
-
SecureRandom.hex(10)
|
48
|
+
def finish_with_state(listeners_state, name, payload)
|
49
|
+
@notifier.finish name, @id, payload, listeners_state
|
43
50
|
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def unique_id
|
54
|
+
SecureRandom.hex(10)
|
55
|
+
end
|
44
56
|
end
|
45
57
|
|
46
58
|
class Event
|
47
|
-
attr_reader :name, :time, :
|
48
|
-
attr_accessor :
|
59
|
+
attr_reader :name, :time, :end, :transaction_id, :children
|
60
|
+
attr_accessor :payload
|
49
61
|
|
50
62
|
def initialize(name, start, ending, transaction_id, payload)
|
51
63
|
@name = name
|
52
64
|
@payload = payload.dup
|
53
|
-
@time = start
|
65
|
+
@time = start ? start.to_f * 1_000.0 : start
|
54
66
|
@transaction_id = transaction_id
|
55
|
-
@end = ending
|
67
|
+
@end = ending ? ending.to_f * 1_000.0 : ending
|
56
68
|
@children = []
|
69
|
+
@cpu_time_start = 0.0
|
70
|
+
@cpu_time_finish = 0.0
|
71
|
+
@allocation_count_start = 0
|
72
|
+
@allocation_count_finish = 0
|
73
|
+
end
|
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
|
+
|
88
|
+
# Record information at the time this event starts
|
89
|
+
def start!
|
90
|
+
@time = now
|
91
|
+
@cpu_time_start = now_cpu
|
92
|
+
@allocation_count_start = now_allocations
|
57
93
|
end
|
58
94
|
|
95
|
+
# Record information at the time this event finishes
|
96
|
+
def finish!
|
97
|
+
@cpu_time_finish = now_cpu
|
98
|
+
@end = now
|
99
|
+
@allocation_count_finish = now_allocations
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns the CPU time (in milliseconds) passed since the call to
|
103
|
+
# +start!+ and the call to +finish!+
|
104
|
+
def cpu_time
|
105
|
+
@cpu_time_finish - @cpu_time_start
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns the idle time time (in milliseconds) passed since the call to
|
109
|
+
# +start!+ and the call to +finish!+
|
110
|
+
def idle_time
|
111
|
+
duration - cpu_time
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns the number of allocations made since the call to +start!+ and
|
115
|
+
# the call to +finish!+
|
116
|
+
def allocations
|
117
|
+
@allocation_count_finish - @allocation_count_start
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns the difference in milliseconds between when the execution of the
|
121
|
+
# event started and when it ended.
|
122
|
+
#
|
123
|
+
# ActiveSupport::Notifications.subscribe('wait') do |*args|
|
124
|
+
# @event = ActiveSupport::Notifications::Event.new(*args)
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# ActiveSupport::Notifications.instrument('wait') do
|
128
|
+
# sleep 1
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# @event.duration # => 1000.138
|
59
132
|
def duration
|
60
|
-
|
133
|
+
self.end - time
|
61
134
|
end
|
62
135
|
|
63
136
|
def <<(event)
|
@@ -67,6 +140,33 @@ module ActiveSupport
|
|
67
140
|
def parent_of?(event)
|
68
141
|
@children.include? event
|
69
142
|
end
|
143
|
+
|
144
|
+
private
|
145
|
+
def now
|
146
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
|
147
|
+
end
|
148
|
+
|
149
|
+
begin
|
150
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
151
|
+
|
152
|
+
def now_cpu
|
153
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
|
154
|
+
end
|
155
|
+
rescue
|
156
|
+
def now_cpu # rubocop:disable Lint/DuplicateMethods
|
157
|
+
0.0
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
if GC.stat.key?(:total_allocated_objects)
|
162
|
+
def now_allocations
|
163
|
+
GC.stat(:total_allocated_objects)
|
164
|
+
end
|
165
|
+
else # Likely on JRuby, TruffleRuby
|
166
|
+
def now_allocations
|
167
|
+
0
|
168
|
+
end
|
169
|
+
end
|
70
170
|
end
|
71
171
|
end
|
72
172
|
end
|