57 lines
1.6 KiB
Go
57 lines
1.6 KiB
Go
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 `<node>.<module>`): 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 `<node>.<module>`
|
|
}
|
|
|
|
// Put takes a change of the have bucket in and answers whether a module's healthy state changed. A node's own key
|
|
// (`<node>.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]
|
|
}
|