Skip to content

Instantly share code, notes, and snippets.

@hakobera
Created December 28, 2015 23:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hakobera/f1166b697e0e3f5f37f8 to your computer and use it in GitHub Desktop.
Save hakobera/f1166b697e0e3f5f37f8 to your computer and use it in GitHub Desktop.
require 'tsort'
class DAG
include TSort
def initialize
@tasks = {}
end
def tsort_each_node(&block)
@tasks.each_key(&block)
end
def tsort_each_child(node, &block)
@tasks.fetch(node).each(&block)
end
def add_task(task)
_add_task(nil, task)
end
private
def _add_task(parent, task)
unless @tasks[task]
@tasks[task] = task.requires
task.requires.each do |r|
_add_task(task, r)
end
end
task
end
end
require_relative 'workflow'
require_relative 'task'
require_relative 'file_target'
class EchoTask < Task
def output
FileTarget.new("/tmp/#{self.class.name}.txt")
end
def run
puts "#{self.class.name}#run"
File.write(output.path, "done")
end
end
class TaskA < EchoTask
def requires
[ TaskB.new, TaskC.new ]
end
end
class TaskB < EchoTask
def requires
[ TaskD.new ]
end
end
class TaskC < EchoTask
def requires
[ TaskD.new ]
end
end
class TaskD < EchoTask
end
Workflow.new.run(TaskA.new)
require_relative 'target'
class FileTarget < Target
attr_reader :path
def initialize(path)
@path = path
end
def exists?
File.exist?(path)
end
end
class Target
def exists?
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end
end
class Task
def output
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end
def run
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end
def requires
[] # If you need to define task dependencies, override in subclass
end
def eql?(other)
self.hash == other.hash
end
def hash
self.class.name.hash
end
end
require_relative 'dag'
class Workflow
def run(task)
dag = DAG.new
dag.add_task(task)
dag.tsort.each do |t|
t.run unless t.output.exists?
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment