package buildrun import ( "sync" "git.novox.be/novox/mesh-sdk/go/delivery" ) // HaveSet holds what each node's node-engine says of each module on it (node-engine_have, key `.`): the // builder reads it to know whether a node's build module is running and healthy, since a build module whose installed // toolchain is not the one its recipe builds with is unhealthy (mesh-build-go build_go_health) and its steps would // refuse (ADR 0478 clause 3). A module the node-engine has written no key of is not healthy. Safe for use from the watch // and from a build at once. type HaveSet struct { mu sync.Mutex healthy map[string]bool // by `.` } // Put takes a change of the have bucket in and answers whether a module's healthy state changed. A node's own key // (`.node`) and a value that is not a have are left out. func (s *HaveSet) Put(key string, value []byte, deleted bool) bool { node, module, isNode, err := delivery.ParseHaveKey(key) if err != nil || isNode { return false } ok := false if !deleted { h, err := delivery.DecodeHave(value) if err != nil { return false } ok = h.Phase == delivery.PhaseRunning && h.Health == delivery.HealthOK } k := node + "." + module s.mu.Lock() defer s.mu.Unlock() if s.healthy[k] == ok { return false } if s.healthy == nil { s.healthy = map[string]bool{} } if ok { s.healthy[k] = true } else { delete(s.healthy, k) } return true } // Healthy is whether the module on the node was last seen running and healthy. func (s *HaveSet) Healthy(node, module string) bool { s.mu.Lock() defer s.mu.Unlock() return s.healthy[node+"."+module] }