Say a restart count runs from when the node-engine began watching it
mesh/merge-gate pass: builds mesh-controller → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group fix/458-restarts-say-what-they-count delivered: every member is delivered

The engine reports its own count, kept across recreates and starts by hand, not
systemd's NRestarts or the runtime's RestartCount (novox/hq issue 458).
This commit is contained in:
2026-10-12 10:46:38 +02:00
parent 63079e2c67
commit cde0dc287b
2 changed files with 12 additions and 10 deletions
+8 -6
View File
@@ -497,7 +497,8 @@ func moduleUnhealthyObservation(module, node string, rs []inventory.ResourceHeal
continue
}
words = append(words, fmt.Sprintf("its %s %s %s", r.Kind, r.Resource, reasonWords(r)))
// The restart count runs from the last start or creation, not from the state's since (novox/hq issue 458).
// The restart count runs from when the engine began watching it, not from the state's since (novox/hq
// issue 458).
said = append(said, fmt.Sprintf("%s (%s %s): %s, since %s, %d look(s) in a row, %s",
r.Resource, r.Kind, r.Target, orNotSaid(r.Reason), r.Since.UTC().Format("2006-01-02 15:04:05 MST"),
r.Streak, restartsWords(r.Restarts)))
@@ -514,12 +515,13 @@ func moduleUnhealthyObservation(module, node string, rs []inventory.ResourceHeal
Resolved: fmt.Sprintf("%s works again on %s", module, node)}
}
// restartsWords is a restart count as what it is (novox/hq issue 458): the engine reads systemd's NRestarts,
// which counts only restarts its Restart= setting caused and resets when the unit is started by hand, or the
// runtime's RestartCount, which counts only restart-policy restarts and is lost when the container is
// recreated. So it counts automatic restarts since the last start or creation, never since a state's "since".
// restartsWords is a restart count as what it is (novox/hq issue 458). The engine reports its own count
// (mesh-host's liveness judge, kept.Counted): every rise of systemd's NRestarts or the runtime's RestartCount
// after a start's grace, so only restarts by the Restart= setting or the restart policy. It keeps the count
// across a recreate, a start by hand and its own restarts, and forgets it only when the resource is no longer
// declared. So it counts automatic restarts since the engine began watching it, never since a state's "since".
func restartsWords(n int) string {
return fmt.Sprintf("%d automatic restart(s) since it was last started or created", n)
return fmt.Sprintf("%d automatic restart(s) since the node-engine began watching it", n)
}
// reasonWords is why a resource is unhealthy, as a person reads it.