class Fasten::TaskManager

Attributes

done[R]
failed[R]
pending[R]
runner[R]
running[R]
targets[R]

Public Class Methods

new(runner:, targets: []) click to toggle source
Calls superclass method
# File lib/fasten/task_manager.rb, line 5
def initialize(runner:, targets: [])
  super()

  @map = {}
  @done = []
  @failed = []
  @pending = []
  @running = []
  @targets = targets
  @waiting = nil
  @runner = runner
end

Public Instance Methods

<<(task) click to toggle source
Calls superclass method
# File lib/fasten/task_manager.rb, line 26
def <<(task)
  raise "Object class #{task.class} not allowed" unless task.is_a? Task
  raise "Task '#{task.name}' already defined" if @map[task.name]

  @map[task.name] = task
  @waiting = nil
  super
end
failed?() click to toggle source
# File lib/fasten/task_manager.rb, line 78
def failed?
  !failed.empty?
end
next() click to toggle source
# File lib/fasten/task_manager.rb, line 35
def next
  waiting.shift
end
no_running?() click to toggle source
# File lib/fasten/task_manager.rb, line 66
def no_running?
  running.empty?
end
no_waiting?() click to toggle source
# File lib/fasten/task_manager.rb, line 62
def no_waiting?
  waiting.empty?
end
push(*items) click to toggle source
# File lib/fasten/task_manager.rb, line 18
def push(*items)
  items.each do |item|
    self << item
  end

  self
end
running?() click to toggle source
# File lib/fasten/task_manager.rb, line 74
def running?
  !running.empty?
end
update(task) click to toggle source
# File lib/fasten/task_manager.rb, line 39
def update(task)
  pending.delete task

  if task.state == :DONE
    done << task
    task.dependants.each { |dependant_task| dependant_task.depends.delete task }

    move_pending_to_waiting
  else
    failed << task
  end
end
waiting() click to toggle source
# File lib/fasten/task_manager.rb, line 52
def waiting
  return @waiting if @waiting

  reset
  setup_dependencies
  setup_targets
  setup_scores
  move_pending_to_waiting
end
waiting?() click to toggle source
# File lib/fasten/task_manager.rb, line 70
def waiting?
  !waiting.empty?
end

Protected Instance Methods

mark_needed(task) click to toggle source
# File lib/fasten/task_manager.rb, line 137
def mark_needed(task)
  return unless task.state == :IDLE

  task.state = :NEED
  task.depends.each do |depend_task|
    mark_needed(depend_task)
  end
end
move_pending_to_waiting() click to toggle source
# File lib/fasten/task_manager.rb, line 152
def move_pending_to_waiting
  to_move = pending.select { |task| task.depends.count.zero? }

  @pending -= to_move
  @waiting += to_move
  case @runner.priority
  when :dependants
    @waiting.sort_by!.with_index do |task, index|
      task.state = :WAIT
      [-task.run_score, index]
    end
  when :dependants_avg
    @waiting.sort_by!.with_index do |task, index|
      task.state = :WAIT
      last_avg = task.last_avg || 0
      [-task.run_score, -last_avg, index]
    end
  else
    raise "Unknown priority #{@runner.priority}"
  end
end
reset() click to toggle source
# File lib/fasten/task_manager.rb, line 84
def reset
  by_state = group_by(&:state)

  @done = by_state.delete(:DONE) || []
  @failed = by_state.delete(:FAIL) || []
  @running = by_state.delete(:RUNNING) || []
  @waiting = []

  @pending = by_state.values.flatten.each do |task|
    task.depends = []
    task.dependants = []
    task.state = nil
  end
end
setup_dependencies() click to toggle source
# File lib/fasten/task_manager.rb, line 99
def setup_dependencies
  @pending.each do |task|
    next unless task.after

    [task.after].flatten.each do |after|
      after_task = after.is_a?(Task) ? after : @map[after]
      raise "Dependency task '#{after}' not found on task '#{task.name}'." unless after_task

      task.depends << after_task
      after_task.dependants << task
    end
  end
end
setup_pending() click to toggle source
# File lib/fasten/task_manager.rb, line 126
def setup_pending
  @pending.reject { |task| task.state == :NEED }.each do |task|
    @pending.delete task
    delete task
  end

  @pending.each do |task|
    task.state = nil
  end
end
setup_scores() click to toggle source
# File lib/fasten/task_manager.rb, line 146
def setup_scores
  each do |task|
    task.run_score = task.dependants.count
  end
end
setup_targets() click to toggle source
# File lib/fasten/task_manager.rb, line 113
def setup_targets
  return if @targets.empty?

  @targets.each do |target|
    task = target.is_a?(Task) ? target : @map[target]
    raise "Target task #{target} not found" unless task

    mark_needed(task)
  end

  setup_pending
end