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
20 def initialize(transaction)
21   @transaction = transaction
22   @event_queues = {}
23   @events = []
24 end

Public Instance Methods

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

Respond to any queued events for this resource.

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

Private Instance Methods

add_callback_status_event(resource, callback, message, status) click to toggle source
    # File lib/puppet/transaction/event_manager.rb
167 def add_callback_status_event(resource, callback, message, status)
168   options = { message: message, status: status, name: callback.to_s }
169   event = resource.event options
170   transaction.resource_status(resource) << event if event
171 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
143 def process_callback(resource, callback, events)
144   if !process_callback?(resource, events)
145     process_noop_events(resource, callback, events)
146     return false
147   end
148 
149   resource.send(callback)
150 
151   if not resource.is_a?(Puppet::Type.type(:whit))
152     message = n_("Triggered '%{callback}' from %{count} event", "Triggered '%{callback}' from %{count} events", events.length) % { count: events.length, callback: callback }
153     resource.notice message
154     add_callback_status_event(resource, callback, message, "success")
155   end
156 
157   return true
158 rescue => detail
159   resource_error_message = _("Failed to call %{callback}: %{detail}") % { callback: callback, detail: detail }
160   resource.err(resource_error_message)
161   transaction.resource_status(resource).failed_to_restart = true
162   transaction.resource_status(resource).fail_with_event(resource_error_message)
163   resource.log_exception(detail)
164   return false
165 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
132 def process_callback?(resource, events)
133   !(events.all? { |e| e.status == "noop" } || resource.noop?)
134 end
process_noop_events(resource, callback, events) click to toggle source
    # File lib/puppet/transaction/event_manager.rb
173 def process_noop_events(resource, callback, events)
174   resource.notice n_("Would have triggered '%{callback}' from %{count} event", "Would have triggered '%{callback}' from %{count} events", events.length) % { count: events.length, callback: callback }
175 
176   # And then add an event for it.
177   queue_events(resource, [resource.event(:status => "noop", :name => :noop_restart)])
178 end