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 20 def initialize(transaction) 21 @transaction = transaction 22 @event_queues = {} 23 @events = [] 24 end
Public Instance Methods
# 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
# 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
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
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
# 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
# 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
# File lib/puppet/transaction/event_manager.rb 26 def relationship_graph 27 transaction.relationship_graph 28 end
Private Instance Methods
# 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
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
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
# 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