github.com/adityamillind98/nomad@v0.11.8/nomad/blocked_evals_system.go (about) 1 package nomad 2 3 import "github.com/hashicorp/nomad/nomad/structs" 4 5 // systemEvals are handled specially, each job may have a blocked eval on each node 6 type systemEvals struct { 7 // byJob maps a jobID to a nodeID to that job's single blocked evalID on that node 8 byJob map[structs.NamespacedID]map[string]string 9 10 // byNode maps a nodeID to a set of evalIDs 11 byNode map[string]map[string]bool 12 13 // evals maps evalIDs to an eval and token 14 evals map[string]*wrappedEval 15 } 16 17 func newSystemEvals() *systemEvals { 18 return &systemEvals{ 19 evals: map[string]*wrappedEval{}, 20 byJob: map[structs.NamespacedID]map[string]string{}, 21 byNode: map[string]map[string]bool{}, 22 } 23 } 24 25 func (s *systemEvals) Add(eval *structs.Evaluation, token string) { 26 // store the eval by node id 27 if _, ok := s.byNode[eval.NodeID]; !ok { 28 s.byNode[eval.NodeID] = make(map[string]bool) 29 } 30 31 s.byNode[eval.NodeID][eval.ID] = true 32 s.evals[eval.ID] = &wrappedEval{eval: eval, token: token} 33 34 // link the job to the node for cleanup 35 jobID := structs.NewNamespacedID(eval.JobID, eval.Namespace) 36 if _, ok := s.byJob[jobID]; !ok { 37 s.byJob[jobID] = make(map[string]string) 38 } 39 40 // if we're displacing the old blocked id for this job+node, delete it first 41 if prevID, ok := s.byJob[jobID][eval.NodeID]; ok { 42 prev, _ := s.Get(prevID) 43 s.Remove(prev.eval) 44 } 45 46 // set this eval as the new eval for this job on this node 47 s.byJob[jobID][eval.NodeID] = eval.ID 48 } 49 50 func (s *systemEvals) Get(evalID string) (*wrappedEval, bool) { 51 w, ok := s.evals[evalID] 52 return w, ok 53 } 54 55 func (s *systemEvals) Remove(eval *structs.Evaluation) { 56 // delete the job index if this eval is the currently listed blocked eval 57 jobID := structs.NewNamespacedID(eval.JobID, eval.Namespace) 58 e, ok := s.byJob[jobID][eval.NodeID] 59 if ok && e == eval.ID { 60 delete(s.byJob[jobID], eval.NodeID) 61 } 62 63 // delete this eval from the node index, and then the map for this node if empty 64 delete(s.byNode[eval.NodeID], eval.ID) 65 if len(s.byNode[eval.NodeID]) == 0 { 66 delete(s.byNode, eval.NodeID) 67 } 68 69 // delete the eval itself 70 delete(s.evals, eval.ID) 71 } 72 73 func (s *systemEvals) NodeEvals(nodeID string) (map[*structs.Evaluation]string, bool) { 74 out := map[*structs.Evaluation]string{} 75 for eID := range s.byNode[nodeID] { 76 if w, ok := s.Get(eID); ok { 77 out[w.eval] = w.token 78 } 79 } 80 81 ok := len(out) > 0 82 return out, ok 83 } 84 85 func (s *systemEvals) JobEvals(jobID structs.NamespacedID) ([]*structs.Evaluation, bool) { 86 out := []*structs.Evaluation{} 87 _, ok := s.byJob[jobID] 88 for _, eID := range s.byJob[jobID] { 89 if e, ok := s.Get(eID); ok { 90 out = append(out, e.eval) 91 } 92 } 93 return out, ok 94 }