Created
July 5, 2009 23:46
-
-
Save lak/141186 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class SortedWalking | |
| class Vertex | |
| attr_accessor :weight, :label | |
| def initialize(label, weight = nil) | |
| @label = label | |
| @weight = weight || 5 | |
| end | |
| def to_s | |
| label | |
| end | |
| end | |
| class ShadowMap | |
| Shadow = Struct.new(:failed, :noop, :events, :dependents) | |
| attr_reader :map | |
| def initialize | |
| @map = {} | |
| @failed = {} | |
| end | |
| def [](vertex) | |
| @map[vertex] | |
| end | |
| # Store a failure for later. | |
| def fail(vertex, reason) | |
| @failed[vertex] ||= [] | |
| @failed[vertex] << resource | |
| end | |
| def shadow(edge) | |
| target_shadow = find_or_make_shadow(edge) | |
| add_failures(edge.target, target_shadow) | |
| target_shadow | |
| end | |
| private | |
| def add_failures(vertex, shadow) | |
| if failures = @failed[vertex] | |
| shadow.failures += failures | |
| end | |
| end | |
| def find_or_make_shadow(edge) | |
| unless target_shadow = map[edge.target] | |
| unless source_shadow = map[edge.source] | |
| # This should be the top-level initialization | |
| map[edge.source] = Shadow.new([], [], [], []) | |
| end | |
| target_shadow = map[edge.target] = make_target_shadow(target, source_shadow) | |
| end | |
| end | |
| def make_target_shadow(target, source_shadow) | |
| # We clone so that each shadow has its own array, rather than using | |
| # the same instance variables, as a 'dup' would do. | |
| shadow = source_shadow.clone | |
| end | |
| end | |
| def vertex(name) | |
| @graph.vertices.find { |v| v.label == name } || Vertex.new(name) | |
| end | |
| def add_edge(source, target, type = :container) | |
| edge = Puppet::Relationship.new(vertex(source), vertex(target)) | |
| edge.type = type | |
| @graph.add_edge(edge) | |
| end | |
| def initialize | |
| Puppet[:graphdir] = "/Users/luke/Desktop/graph_testing" | |
| Puppet[:graph] = true | |
| @graph = Puppet::SimpleGraph.new | |
| add_edge("top", "a") | |
| add_edge("top", "A") | |
| add_edge("a", "b") | |
| add_edge("b", "c") | |
| add_edge("a", "d") | |
| add_edge("d", "e") | |
| add_edge("d", "f") | |
| add_edge("a", "g") | |
| add_edge("A", "B") | |
| add_edge("B", "C") | |
| add_edge("A", "D") | |
| add_edge("D", "E") | |
| add_edge("D", "F") | |
| add_edge("A", "G") | |
| # Now add our dependency edges | |
| #@dependencies = {"B" => "b", "C" => "d", "D" => "d"} | |
| #@dependencies = {"B" => "b", "C" => "d"} | |
| #@dependencies = {"B" => "b", "C" => "d", "D" => "g"} | |
| #@dependencies = {"A" => "a"} | |
| #@dependencies = {} | |
| #@weights = {} | |
| #@weights = { "A" => 4, "d" => 1 } | |
| @failures = %w{f} | |
| add_dependencies | |
| add_weights | |
| @shadow_map = ShadowMap.new | |
| end | |
| def add_dependencies | |
| return unless defined?(@dependencies) | |
| @dependencies.each do |source, target| | |
| add_edge(source, target, :dependency) | |
| end | |
| end | |
| def add_weights | |
| return unless defined?(@weights) | |
| @weights.each do |v, weight| | |
| vertex(v).weight = weight | |
| end | |
| end | |
| def apply_shadow(edge) | |
| return unless edge.container? | |
| shadow = @shadow_map.shadow(edge) | |
| # Track all of our dependents | |
| shadow.dependents += dependent_edges(edge.target) | |
| # Track failure state | |
| if @failures.include?(edge.target.label) | |
| shadow.failed << "%s failed" % edge.target.label | |
| # Mark all of our dependents as failed, too | |
| shadow.dependents.each do |edge| | |
| @shadow_map.fail(edge.source, shadow.failed[-1]) | |
| end | |
| end | |
| shadow | |
| end | |
| def dependent_edges(vertex) | |
| adjacent(vertex, :direction => :in, :type => :edges).reject { |e| e.container? } | |
| end | |
| def run | |
| top = @graph.vertices.find { |v| v.label == "top" } | |
| result = [] | |
| @graph.dfs_walk(top, :out) do |edge| | |
| begin | |
| #apply_shadow(edge) | |
| rescue => detail | |
| puts "Skipping %s: %s" % [edge.target, detail] | |
| next | |
| end | |
| result << edge.target.label unless result.include?(edge.target.label) | |
| end | |
| @graph.write_graph("test") | |
| p result | |
| end | |
| end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment