Keep what each machine says of what it runs, raise it, and gate on it (hq ADR 0240, to-be 48 Phase A)

The gate judged a module by what the mesh saw from outside, so a container that
crash-looped after it applied passed it. Each machine's node-engine now states
the health of every long-running resource it runs; the controller keeps the
newest statement per machine, raises module.<module>.<machine>.unhealthy on the
second statement in a row, clears it on the first that does not say it, and the
gate passes a module only when every long-running resource of it is stated
healthy since the send. An engine that states nothing is judged as before.
This commit is contained in:
jochen
2026-10-07 02:28:16 +02:00
parent 5d3e52219b
commit 1cc6a2d759
22 changed files with 997 additions and 5 deletions
+12
View File
@@ -105,6 +105,10 @@ type gateFacts struct {
// holder is who holds the controller lease, for judging the controller.
holder *lease.Holder
holderErr error
// health is each machine's newest health statement (ADR 0240); a machine absent never stated one.
// healthErr is why they could not be read.
health map[string]inventory.NodeHealth
healthErr error
}
// gatherGateFacts reads what a judging needs, from the store, the bus and this controller's memory. A
@@ -127,6 +131,9 @@ var gatherGateFacts = func(ctx context.Context, open *stores, component string)
for _, n := range nodes {
f.engines[n.Name] = n.HostVersion
}
// What each machine says of its long-running resources (ADR 0240): unreadable is said, never read as
// healthy.
f.health, f.healthErr = inv.Healths(ctx)
if d := doctorFrom; d != nil {
if d.keeper != nil {
f.judged = true
@@ -241,6 +248,11 @@ func judgeHealth(module, component string, m catalogue.Manifest, machine string,
return healthNotYet, fmt.Sprintf("the node tools on %s do not serve %s's tools", machine, module)
}
}
// **And what it runs is stated healthy** (ADR 0240 §4): every long-running resource of it on that
// machine, in a statement heard since the send. A resource still starting makes the judging wait.
if h, why := moduleHealthWord(module, machine, since, f); h != healthGood {
return h, why
}
}
return healthGood, ""
}