└── lib └── task.rb /lib/task.rb: -------------------------------------------------------------------------------- 1 | require 'set' 2 | 3 | class Task 4 | attr_reader :name, :task, :status, :deps 5 | 6 | def initialize(name, &task) 7 | @name = name 8 | @task = task 9 | @status = :unborn 10 | @deps = Set.new 11 | @mutex = Mutex.new 12 | end 13 | 14 | def add_dependency(tasks) 15 | tasks.each do |t| 16 | raise "#{t} should be an object of class Task" unless t.is_a? Task 17 | @deps.add t 18 | end 19 | end 20 | 21 | def do_it 22 | @mutex.synchronize do 23 | unless @status == :unborn 24 | return 25 | end 26 | @status = :pending 27 | 28 | if @deps.empty? 29 | @status = :done 30 | else 31 | tasks = [] 32 | @deps.each do |t| 33 | tasks << Thread.new { t.do_it } 34 | end 35 | tasks.each { |t| t.join } 36 | end 37 | @status = :running 38 | @task.call 39 | @status = :done 40 | end 41 | end 42 | end 43 | 44 | t1 = Task.new "t1", &lambda { puts "t1" } 45 | t2 = Task.new "t2", &lambda { puts "t2" } 46 | t3 = Task.new "t3", &lambda { puts "t3" } 47 | t4 = Task.new "t4", &lambda { puts "t4" } 48 | t5 = Task.new "t5", &lambda { puts "t5" } 49 | t6 = Task.new "t6", &lambda { puts "t6" } 50 | t7 = Task.new "t7", &lambda { puts "t7" } 51 | t1.add_dependency [t2, t3] 52 | t2.add_dependency [t4] 53 | t3.add_dependency [t4, t6, t7] 54 | t4.add_dependency [t5, t6] 55 | t1.do_it 56 | --------------------------------------------------------------------------------