Skip to content

Instantly share code, notes, and snippets.

@dideler
Last active January 6, 2024 15:13
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save dideler/07c353deb8071646a39c09de6d96afe7 to your computer and use it in GitHub Desktop.
Save dideler/07c353deb8071646a39c09de6d96afe7 to your computer and use it in GitHub Desktop.
Example of building a Directed Acyclic Graph (DAG) for tasks that depend on each others

Requires a YAML file with mappings, e.g.

:task_a:
  :task_b:
    :task_c:
  :task_d:
  :task_e:

View interactive graph:

brew install xdot
xdot graph.dot

View static graph:

brew install graphviz
dot graph.dot -Tsvg -o graph.svg   # SVG
dot graph.dot -Tsvgz -o graph.svgz # Compressed SVG

Recommend using Gapplin to view the SVG files.

source 'http://rubygems.org'
gem 'plexus'
gem 'gratr' # dependency of plexus to visualize graphs
require 'plexus'
require 'yaml'
class TaskDag
include Plexus
def initialize(filepath = File.join('config', 'task_mappings.yml'))
@dag = DirectedGraph.new # alias of Digraph
@filepath = filepath
end
def build
add_vertices_and_edges
end
def ancestors(task)
dag.ancestors(task)
end
def root(task)
ancestors(task).last
end
def visualize
filename = dag.write_to_graphic_file and puts "Created #{filename}"
end
private
attr_reader :dag, :filepath
def add_vertices_and_edges(tasks = yml_tasks)
tasks.each_pair do |task, child_tasks|
next if child_tasks.nil?
child_tasks.keys.each do |child|
dag.add_edge!(task, child)
end
add_vertices_and_edges(child_tasks)
end
end
def yml_tasks
@yml_tasks ||= YAML.load_file(filepath)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment