class Transaction::EventManager

This class stores, routes, and responds to events generated while evaluating a transaction.

@api private

Attributes

events[R]

@!attribute [r] events

@todo Determine if this instance variable is used for anything aside from testing.
@return [Array<Puppet::Transaction::Events>] A list of events that can be
  handled by the target resource. Events that cannot be handled by the
  target resource will be discarded.
transaction[R]

@!attribute [r] transaction

@return [Puppet::Transaction] The transaction associated with this event manager.

Public Class Methods

new(transaction) click to toggle source
   # File lib/puppet/transaction/event_manager.rb
21 def initialize(transaction)
22   @transaction = transaction
23   @event_queues = {}
24   @events = []
25 end

Public Instance Methods

dequeue_all_events_for_resource(target) click to toggle source
   # File lib/puppet/transaction/event_manager.rb
86 def dequeue_all_events_for_resource(target)
87   callbacks = @event_queues[target]
88   if callbacks && !callbacks.empty?
89     target.info _("Unscheduling all events on %{target}") % { target: target }
90     @event_queues[target] = {}
91   end
92 end
dequeue_events_for_resource(target, callback) click to toggle source
   # File lib/puppet/transaction/event_manager.rb
94 def dequeue_events_for_resource(target, callback)
95   target.info _("Unscheduling %{callback} on %{target}") % { callback: callback, target: target }
96   @event_queues[target][callback] = [] if @event_queues[target]
97 end
process_events(resource) click to toggle source

Respond to any queued events for this resource.

   # File lib/puppet/transaction/event_manager.rb
32 def process_events(resource)
33   restarted = false
34   queued_events(resource) do |callback, events|
35     r = process_callback(resource, callback, events)
36     restarted ||= r
37   end
38 
39   if restarted
40     queue_events(resource, [resource.event(:name => :restarted, :status => "success")])
41 
42     transaction.resource_status(resource).restarted = true
43   end
44 end
queue_events(resource, events) click to toggle source

Queues events for other resources to respond to. All of these events have to be from the same resource.

@param resource [Puppet::Type] The resource generating the given events @param events [Array<Puppet::Transaction::Event>] All events generated by this resource @return [void]

   # File lib/puppet/transaction/event_manager.rb
52 def queue_events(resource, events)
53   #@events += events
54 
55   # Do some basic normalization so we're not doing so many
56   # graph queries for large sets of events.
57   events.inject({}) do |collection, event|
58     collection[event.name] ||= []
59     collection[event.name] << event
60     collection
61   end.collect do |name, list|
62     # It doesn't matter which event we use - they all have the same source
63     # and name here.
64     event = list[0]
65 
66     # Collect the targets of any subscriptions to those events.  We pass
67     # the parent resource in so it will override the source in the events,
68     # since eval_generated children can't have direct relationships.
69     received = (event.name != :restarted)
70     relationship_graph.matching_edges(event, resource).each do |edge|
71       received ||= true unless edge.target.is_a?(Puppet::Type.type(:whit))
72       method = edge.callback
73       next unless method
74       next unless edge.target.respond_to?(method)
75 
76       queue_events_for_resource(resource, edge.target, method, list)
77     end
78     @events << event if received
79 
80     queue_events_for_resource(resource, resource, :refresh, [event]) if resource.self_refresh? and ! resource.deleting?
81   end
82 
83   dequeue_events_for_resource(resource, :refresh) if events.detect { |e| e.invalidate_refreshes }
84 end
queue_events_for_resource(source, target, callback, events) click to toggle source
    # File lib/puppet/transaction/event_manager.rb
 99 def queue_events_for_resource(source, target, callback, events)
100   whit = Puppet::Type.type(:whit)
101 
102   # The message that a resource is refreshing the completed-whit for its own class
103   # is extremely counter-intuitive. Basically everything else is easy to understand,
104   # if you suppress the whit-lookingness of the whit resources
105   refreshing_c_whit = target.is_a?(whit) && target.name =~ /^completed_/
106 
107   if refreshing_c_whit
108     source.debug "The container #{target} will propagate my #{callback} event"
109   else
110     source.info _("Scheduling %{callback} of %{target}") % { callback: callback, target: target }
111   end
112 
113   @event_queues[target] ||= {}
114   @event_queues[target][callback] ||= []
115   @event_queues[target][callback].concat(events)
116 end
queued_events(resource) { |callback, events| ... } click to toggle source
    # File lib/puppet/transaction/event_manager.rb
118 def queued_events(resource)
119   callbacks = @event_queues[resource]
120   return unless callbacks
121   callbacks.each do |callback, events|
122     yield callback, events unless events.empty?
123   end
124 end
relationship_graph() click to toggle source
   # File lib/puppet/transaction/event_manager.rb
27 def relationship_graph
28   transaction.relationship_graph
29 end

Private Instance Methods

add_callback_status_event(resource, callback, message, status) click to toggle source
    # File lib/puppet/transaction/event_manager.rb
168 def add_callback_status_event(resource, callback, message, status)
169   options = { message: message, status: status, name: callback.to_s }
170   event = resource.event options
171   transaction.resource_status(resource) << event if event
172 end
process_callback(resource, callback, events) click to toggle source

Processes callbacks for a given resource.

@param resource [Puppet::Type] The resource receiving the callback. @param callback [Symbol] The name of the callback method that will be invoked. @param events [Array<Puppet::Transaction::Event>] A list of events

associated with this callback and resource.

@return [true, false] Whether the callback was successfully run.

    # File lib/puppet/transaction/event_manager.rb
144 def process_callback(resource, callback, events)
145   if !process_callback?(resource, events)
146     process_noop_events(resource, callback, events)
147     return false
148   end
149 
150   resource.send(callback)
151 
152   if not resource.is_a?(Puppet::Type.type(:whit))
153     message = n_("Triggered '%{callback}' from %{count} event", "Triggered '%{callback}' from %{count} events", events.length) % { count: events.length, callback: callback }
154     resource.notice message
155     add_callback_status_event(resource, callback, message, "success")
156   end
157 
158   return true
159 rescue => detail
160   resource_error_message = _("Failed to call %{callback}: %{detail}") % { callback: callback, detail: detail }
161   resource.err(resource_error_message)
162   transaction.resource_status(resource).failed_to_restart = true
163   transaction.resource_status(resource).fail_with_event(resource_error_message)
164   resource.log_exception(detail)
165   return false
166 end
process_callback?(resource, events) click to toggle source

Should the callback for this resource be invoked? @param resource [Puppet::Type] The resource to be refreshed @param events [Array<Puppet::Transaction::Event>] A list of events

associated with this callback and resource.

@return [true, false] Whether the callback should be run.

    # File lib/puppet/transaction/event_manager.rb
133 def process_callback?(resource, events)
134   !(events.all? { |e| e.status == "noop" } || resource.noop?)
135 end
process_noop_events(resource, callback, events) click to toggle source
    # File lib/puppet/transaction/event_manager.rb
174 def process_noop_events(resource, callback, events)
175   resource.notice n_("Would have triggered '%{callback}' from %{count} event", "Would have triggered '%{callback}' from %{count} events", events.length) % { count: events.length, callback: callback }
176 
177   # And then add an event for it.
178   queue_events(resource, [resource.event(:status => "noop", :name => :noop_restart)])
179 end