61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"sort"
|
|
|
|
"git.cin.su/m/Assistant/contracts/work"
|
|
)
|
|
|
|
var (
|
|
ErrGraphBudgetExceeded = errors.New("work graph budget exceeded")
|
|
ErrConflictUnresolved = errors.New("conflict resolution is not explicit")
|
|
)
|
|
|
|
func ScheduleReadyNodes(graph work.WorkGraph, active int) ([]work.GraphNodeID, error) {
|
|
if err := ValidateWorkGraph(graph); err != nil {
|
|
return nil, err
|
|
}
|
|
if active < 0 || active > graph.Budget.MaxParallel {
|
|
return nil, ErrGraphBudgetExceeded
|
|
}
|
|
ready, err := ReadyGraphNodes(graph)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
available := graph.Budget.MaxParallel - active
|
|
if len(ready) > available {
|
|
ready = ready[:available]
|
|
}
|
|
return ready, nil
|
|
}
|
|
|
|
func AdmitGraph(graph work.WorkGraph) (work.WorkGraph, error) {
|
|
if err := ValidateWorkGraph(graph); err != nil {
|
|
return work.WorkGraph{}, err
|
|
}
|
|
for _, node := range graph.Nodes {
|
|
if node.Attempts > graph.Budget.MaxAttempts {
|
|
return work.WorkGraph{}, ErrGraphBudgetExceeded
|
|
}
|
|
}
|
|
graph.State = work.GraphAdmitted
|
|
return graph, nil
|
|
}
|
|
|
|
func ResolveGraphConflict(conflict work.ConflictSet, selectedCandidate string) (work.ConflictSet, error) {
|
|
if conflict.ID == "" || conflict.GraphID == "" || conflict.GraphRevision < 1 || conflict.NodeID == "" || conflict.Resolved || selectedCandidate == "" {
|
|
return work.ConflictSet{}, ErrConflictUnresolved
|
|
}
|
|
candidates := append([]string(nil), conflict.CandidateIDs...)
|
|
sort.Strings(candidates)
|
|
for _, candidate := range candidates {
|
|
if candidate == selectedCandidate {
|
|
conflict.CandidateIDs = candidates
|
|
conflict.Resolved = true
|
|
return conflict, nil
|
|
}
|
|
}
|
|
return work.ConflictSet{}, ErrConflictUnresolved
|
|
}
|