aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2018-07-26 12:03:31 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2018-07-26 12:03:31 -0700
commitb0a16a97762c4cdcf36403d46968930099ddcd0f (patch)
tree24bcdc9b44b25f74e406c669705f8ea9986e5c24 /activesupport
parent0c0dba1caf72f78558554a28ca4fc01923cec6f1 (diff)
downloadrails-b0a16a97762c4cdcf36403d46968930099ddcd0f.tar.gz
rails-b0a16a97762c4cdcf36403d46968930099ddcd0f.tar.bz2
rails-b0a16a97762c4cdcf36403d46968930099ddcd0f.zip
Subscribe to event objects via `subscribe_event`
Fanout notifier can send event objects to subscribers now. Also moved `end` lower in the `finish!` method to guarantee that CPU time is shorter than real time.
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb38
-rw-r--r--activesupport/lib/active_support/notifications/instrumenter.rb2
-rw-r--r--activesupport/test/notifications_test.rb17
3 files changed, 56 insertions, 1 deletions
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index 25aab175b4..91d8491c7e 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -27,6 +27,15 @@ module ActiveSupport
subscriber
end
+ def subscribe_event(pattern = nil, &block)
+ subscriber = Subscribers.event_object_subscriber pattern, block
+ synchronize do
+ @subscribers << subscriber
+ @listeners_for.clear
+ end
+ subscriber
+ end
+
def unsubscribe(subscriber_or_name)
synchronize do
case subscriber_or_name
@@ -76,6 +85,14 @@ module ActiveSupport
subscriber = Timed.new pattern, listener
end
+ wrap_all pattern, subscriber
+ end
+
+ def self.event_object_subscriber(pattern, block)
+ wrap_all pattern, EventObject.new(pattern, block)
+ end
+
+ def self.wrap_all(pattern, subscriber)
unless pattern
AllMessages.new(subscriber)
else
@@ -130,6 +147,27 @@ module ActiveSupport
end
end
+ class EventObject < Evented
+ def start(name, id, payload)
+ stack = Thread.current[:_event_stack] ||= []
+ event = build_event name, id, payload
+ event.start!
+ stack.push event
+ end
+
+ def finish(name, id, payload)
+ stack = Thread.current[:_event_stack]
+ event = stack.pop
+ event.finish!
+ @delegate.call event
+ end
+
+ private
+ def build_event(name, id, payload)
+ ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
+ end
+ end
+
class AllMessages # :nodoc:
def initialize(delegate)
@delegate = delegate
diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb
index 259cb4db98..72e5064679 100644
--- a/activesupport/lib/active_support/notifications/instrumenter.rb
+++ b/activesupport/lib/active_support/notifications/instrumenter.rb
@@ -76,8 +76,8 @@ module ActiveSupport
end
def finish!
- @end = now
@cpu_time_finish = now_cpu
+ @end = now
@allocation_count_finish = now_allocations
end
diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index d035f993f7..e28560d88b 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -26,6 +26,23 @@ module Notifications
end
end
+ class SubscribeEventObjects < TestCase
+ def test_subscribe_events
+ events = []
+ @notifier.subscribe_event do |event|
+ events << event
+ end
+
+ ActiveSupport::Notifications.instrument("foo")
+ event = events.first
+ assert event, "should have an event"
+ assert_operator event.allocations, :>, 0
+ assert_operator event.cpu_time, :>, 0
+ assert_operator event.idle_time, :>, 0
+ assert_operator event.duration, :>, 0
+ end
+ end
+
class SubscribedTest < TestCase
def test_subscribed
name = "foo"