class Transaction::EventManager
This class stores, routes, and responds to events generated while evaluating a transaction.
@api private
Attributes
@!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.
@!attribute [r] transaction
@return [Puppet::Transaction] The transaction associated with this event manager.
Public Class Methods
# File lib/puppet/transaction/event_manager.rb 21 def initialize(transaction) 22 @transaction = transaction 23 @event_queues = {} 24 @events = [] 25 end
Public Instance Methods
# 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
# 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
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
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
# 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
# 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
# File lib/puppet/transaction/event_manager.rb 27 def relationship_graph 28 transaction.relationship_graph 29 end
Private Instance Methods
# 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
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
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
# 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