lib/cotcube-scheduler/library.rb
# dependency validation considers all jobs unless they are invalid
# 
# for each job all dependencies must be available
#
dependency validation considers all jobs unless they are invalid
for each job all dependencies must be available
dependency validation considers all jobs unless they are invalid for each job all dependencies must be available
def validate_dependencies(mitigations = [])
        checklist = list.
          reject{|z| z[:status] == :invalid }.
          map{ |job|
            {
              name: job.name,
              deps: job.dependencies.map{|z| z[:job] },
              walk: [],
              miss: [],
              circular: []
            }
          }
        checklist_find = ->(name) { checklist.find {|j| j[:name] == name } }
        check_deps = -> (job, deps) {
          deps.each do |dep|
            if found = checklist_find.call(dep)
              found[:walk] << dep
              found[:deps].each do |next_dep|
                if next_dep == job[:name]
                  found[:circular] << found[:name]
                  checklist_find.call(job[:name])[:circular] << found[:name]
                  return
                end
                check_deps.call(job,checklist_find.call(next_dep)[:deps].select{|d| not found[:walk].include?(d) })
              end
            else
              job[:miss] << dep
            end
          end
        }
        checklist.each do |job|
          actual_job = find_by_name job[:name]
          check_deps.call(actual_job, job[:deps])
          if not job[:circular].empty?
            actual_job.invalidate("Job has circular dependencies: #{job[:circular].reject{|z| z == job[:name]}.join(', ')}.")
          elsif not job[:miss].empty?
            actual_job.invalidate("Job has missing dependencies: #{job[:miss].join(', ')}.")
          end
        end
        checklist.map{|z| z[:status] = :ready unless z[:status] == :invalid; z }
      end
def validate_dependencies ( mitigations = [ ] ) checklist = list . reject { | z | z [ :status ] == :invalid } . map { | job | { name : job . name , deps : job . dependencies . map { | z | z [ :job ] } , walk : [ ] , miss : [ ] , circular : [ ] } } checklist_find = -> ( name ) { checklist . find { | j | j [ :name ] == name } } check_deps = -> ( job , deps ) { deps . each do | dep | if found = checklist_find . call ( dep ) found [ :walk ] << dep found [ :deps ] . each do | next_dep | if next_dep == job [ :name ] found [ :circular ] << found [ :name ] checklist_find . call ( job [ :name ] ) [ :circular ] << found [ :name ] return end check_deps . call ( job , checklist_find . call ( next_dep ) [ :deps ] . select { | d | not found [ :walk ] . include? ( d ) } ) end else job [ :miss ] << dep end end } checklist . each do | job | actual_job = find_by_name job [ :name ] check_deps . call ( actual_job , job [ :deps ] ) if not job [ :circular ] . empty? actual_job . invalidate ( "Job has circular dependencies: #{job[:circular].reject{|z| z == job[:name]}.join(', ')}." ) elsif not job [ :miss ] . empty? actual_job . invalidate ( "Job has missing dependencies: #{job[:miss].join(', ')}." ) end end checklist . map { | z | z [ :status ] = :ready unless z [ :status ] == :invalid ; z } end
dependency validation considers all jobs unless they are invalid
for each job all dependencies must be available
dependency validation considers all jobs unless they are invalid for each job all dependencies must be available
# validate, there are no circular dependencies # validate, there are all dependencies available
mitigations
<not_specific>