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 }