class Chef::EventDispatch::Dispatcher

EventDispatch::Dispatcher

The Dispatcher handles receiving event data from the sources (Chef::Client, Resources and Providers, etc.) and publishing the data to the registered subscribers.

Attributes

subscribers[R]

Public Class Methods

new(*subscribers) click to toggle source
# File lib/chef/event_dispatch/dispatcher.rb, line 14
def initialize(*subscribers)
  @subscribers = subscribers
end

Public Instance Methods

call_subscribers(method_name, *args) click to toggle source

@api private

# File lib/chef/event_dispatch/dispatcher.rb, line 66
def call_subscribers(method_name, *args)
  @in_call = true
  subscribers.each do |s|
    # Skip new/unsupported event names
    next unless s.respond_to?(method_name)

    mth = s.method(method_name)
    # Trim arguments to match what the subscriber expects to allow
    # adding new arguments without breaking compat.
    if mth.arity < args.size && mth.arity >= 0
      mth.call(*args.take(mth.arity))
    else
      mth.call(*args)
    end
  end
ensure
  @in_call = false
end
deprecation(message, location = caller(2..2)[0]) click to toggle source

Special case deprecation, since it needs to know its caller

# File lib/chef/event_dispatch/dispatcher.rb, line 50
def deprecation(message, location = caller(2..2)[0])
  enqueue(:deprecation, message, location)
end
enqueue(method_name, *args) click to toggle source
# File lib/chef/event_dispatch/dispatcher.rb, line 36
def enqueue(method_name, *args)
  event_list << [ method_name, *args ]
  process_events_until_done unless @in_call
end
event_list() click to toggle source

Since the cookbook synchronizer will call this object from threads, we have to deal with concurrent access to this object. Since we don't want threads to handle events from other threads, we just use thread local storage.

# File lib/chef/event_dispatch/dispatcher.rb, line 23
def event_list
  Thread.current[:chef_client_event_list] ||= []
end
formatter?() click to toggle source

Check to see if we are dispatching to a formatter @api private

# File lib/chef/event_dispatch/dispatcher.rb, line 56
def formatter?
  subscribers.any? { |s| s.respond_to?(:is_formatter?) && s.is_formatter? }
end
register(subscriber) click to toggle source

Add a new subscriber to the list of registered subscribers

# File lib/chef/event_dispatch/dispatcher.rb, line 28
def register(subscriber)
  subscribers << subscriber
end
unregister(subscriber) click to toggle source
# File lib/chef/event_dispatch/dispatcher.rb, line 32
def unregister(subscriber)
  subscribers.reject! { |x| x == subscriber }
end

Private Instance Methods

process_events_until_done() click to toggle source

events are allowed to enqueue chained events, so pop them off until empty, rather than iterating over the list.

# File lib/chef/event_dispatch/dispatcher.rb, line 90
def process_events_until_done
  call_subscribers(*event_list.shift) until event_list.empty?
end