Files
Assistant/modules/work/domain/graph_scheduler.go
2026-08-22 13:31:39 +03:00

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
}