diff options
Diffstat (limited to 'activesupport/lib/active_support/subscriber.rb')
-rw-r--r-- | activesupport/lib/active_support/subscriber.rb | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb index 34c6f900c1..98be78b41b 100644 --- a/activesupport/lib/active_support/subscriber.rb +++ b/activesupport/lib/active_support/subscriber.rb @@ -31,22 +31,54 @@ module ActiveSupport # Attach the subscriber to a namespace. def attach_to(namespace, subscriber=new, notifier=ActiveSupport::Notifications) + @namespace = namespace + @subscriber = subscriber + @notifier = notifier + subscribers << subscriber + # Add event subscribers for all existing methods on the class. subscriber.public_methods(false).each do |event| - next if %w{ start finish }.include?(event.to_s) + add_event_subscriber(event) + end + end - notifier.subscribe("#{event}.#{namespace}", subscriber) + # Adds event subscribers for all new methods added to the class. + def method_added(event) + # Only public methods are added as subscribers, and only if a notifier + # has been set up. This means that subscribers will only be set up for + # classes that call #attach_to. + if public_method_defined?(event) && notifier + add_event_subscriber(event) end end def subscribers @@subscribers ||= [] end + + protected + + attr_reader :subscriber, :notifier, :namespace + + def add_event_subscriber(event) + return if %w{ start finish }.include?(event.to_s) + + pattern = "#{event}.#{namespace}" + + # don't add multiple subscribers (eg. if methods are redefined) + return if subscriber.patterns.include?(pattern) + + subscriber.patterns << pattern + notifier.subscribe(pattern, subscriber) + end end + attr_reader :patterns # :nodoc: + def initialize @queue_key = [self.class.name, object_id].join "-" + @patterns = [] super end @@ -71,7 +103,7 @@ module ActiveSupport private def event_stack - SubscriberQueueRegistry.get_queue(@queue_key) + SubscriberQueueRegistry.instance.get_queue(@queue_key) end end |