package watch import ( "encoding/json" "time" ) // ChecksBucket is the bucket of the checks the builders are running (mesh-controller internal/broker // CheckRunningBucket). const ChecksBucket = "mesh-controller_checks-running" // checkRecord is the part of a running check's key the watchman reads, as the controller's builder writes it // (mesh-controller internal/link/checks_nats.go CheckRunning): the head being checked. type checkRecord struct { Head string `json:"head"` } // Check is a change in the checks-running bucket. The builder puts a check's key when the check starts and puts it // again at every heartbeat while the check lives, and deletes it when the check ends. Each new revision of the key is // the check moving: the pulse is deleted and written again with the full bound from that revision's time, so only a // check whose builder stops heartbeating for the whole bound is stuck; the key deleted is the check ended. An aged-out // key is the bucket's own expiry of a builder that died: the pulse is left to run out. func (w *Watchman) Check(key string, value []byte, at time.Time, op Op) { w.mu.Lock() defer w.mu.Unlock() switch op { case Expired: return case Delete: w.moved(ChecksBucket, key) return } var rec checkRecord _ = json.Unmarshal(value, &rec) if at.IsZero() { at = w.now() } if _, stalled := w.ttl(w.now().Sub(at)); !stalled { w.stuckMoved(ChecksBucket, key) } w.mirror(ChecksBucket, key, describe("the check of %s to end", key), rec.Head, at, 0) }