diff options
| author | Luke Kanies <luke@madstop.com> | 2009-11-01 13:28:49 -0600 |
|---|---|---|
| committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
| commit | f2ed655d5e5a9b7c61b29cda229b63db2d73064e (patch) | |
| tree | 228e11d5341cbad85d6a57b28e5553557a90c539 /lib/puppet/transaction | |
| parent | 329527f5173d17c9c2b788734033534009efcf04 (diff) | |
Extracting event management into a separate class
Thus pulls all event-related code out of Transaction.
The Transaction class currently creates a single instance
of this class, so it's nowhere near a "real" event manager,
but at least it has very clean integration points and will
be easy to upgrade as needed.
Signed-off-by: Luke Kanies <luke@madstop.com>
Diffstat (limited to 'lib/puppet/transaction')
| -rw-r--r-- | lib/puppet/transaction/event_manager.rb | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/puppet/transaction/event_manager.rb b/lib/puppet/transaction/event_manager.rb new file mode 100644 index 000000000..370938c5e --- /dev/null +++ b/lib/puppet/transaction/event_manager.rb @@ -0,0 +1,90 @@ +require 'puppet/transaction' + +class Puppet::Transaction::EventManager + attr_reader :transaction, :events + + def initialize(transaction) + @transaction = transaction + @event_queues = {} + @events = [] + end + + def relationship_graph + transaction.relationship_graph + end + + # Respond to any queued events for this resource. + def process_events(resource) + restarted = false + queued_events(resource) do |callback, events| + r = process_callback(resource, callback, events) + restarted ||= r + end + + if restarted + queue_event(resource, resource.event(:name => :restarted, :status => "success")) + + transaction.resourcemetrics[:restarted] += 1 + end + end + + # Queue events for other resources to respond to. All of these events have + # to be from the same resource. + def queue_event(resource, event) + @events << event + + # Collect the targets of any subscriptions to those events. We pass + # the parent resource in so it will override the source in the events, + # since eval_generated children can't have direct relationships. + relationship_graph.matching_edges(event, resource).each do |edge| + next unless method = edge.callback + next unless edge.target.respond_to?(method) + + queue_event_for_resource(resource, edge.target, method, event) + end + + if resource.self_refresh? and ! resource.deleting? + queue_event_for_resource(resource, resource, :refresh, event) + end + end + + def queue_event_for_resource(source, target, callback, event) + source.info "Scheduling #{callback} of #{target}" + + @event_queues[target] ||= {} + @event_queues[target][callback] ||= [] + @event_queues[target][callback] << event + end + + def queued_events(resource) + return unless callbacks = @event_queues[resource] + callbacks.each do |callback, events| + yield callback, events + end + end + + private + + def process_callback(resource, callback, events) + # XXX Should it be any event, or all events? + process_noop_events(resource, callback, events) and return false unless events.detect { |e| e.status != "noop" } + resource.send(callback) + + resource.notice "Triggered '#{callback}' from #{events.length} events" + return true + rescue => detail + resource.err "Failed to call #{callback}: #{detail}" + + transaction.resourcemetrics[:failed_restarts] += 1 + puts detail.backtrace if Puppet[:trace] + return false + end + + def process_noop_events(resource, callback, events) + resource.notice "Would have triggered '#{callback}' from #{events.length} events" + + # And then add an event for it. + queue_event(resource, resource.event(:status => "noop", :name => :noop_restart)) + true # so the 'and if' works + end +end |
