controller v0.67.5: startup recreate waits for stack scan

recreateBootStaleApps ran before the stack manager finished scanning (GetStacks
empty) so it found no apps; add a bounded wait for stacks before the one-time
boot-stale recreate. Deterministic guest-reboot convergence.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-15 17:51:26 +02:00
parent be95a16246
commit 783c79016a
2 changed files with 13 additions and 1 deletions
+5 -1
View File
@@ -1,6 +1,10 @@
## Changelog
### v0.67.4 — gate: startup recreate also recovers exited/restarting drive-backed apps (2026-06-15)
### v0.67.5 — gate: startup recreate waits for stack scan + handles exited apps (2026-06-15)
Adds a bounded wait for the stack scan (GetStacks is empty at NewServer time, so the recreate found no
apps) before the one-time boot-stale recreate, and recovers exited/restarting/unhealthy drive-backed
apps (not only recently-started). The deterministic guest-reboot convergence.
Refines v0.67.3's `recreateBootStaleApps`: recreate a present drive-backed app when it is boot-stale
(recently started) OR currently `exited`/`restarting`/`unhealthy` (came up wrong on the empty bind and
+8
View File
@@ -203,6 +203,14 @@ func (s *Server) ReconcileDriveGates() {
// startup recreate (see recreateBootStaleApps) to converge a guest reboot deterministically, then the
// periodic gate.
func (s *Server) driveGateLoop() {
// Wait for the stack scan to complete (GetStacks empty at NewServer time) and the agent to come up,
// so the one-time boot-stale recreate sees the real deployed apps + drive state. Bounded poll.
for i := 0; i < 30; i++ {
if s.stackMgr != nil && len(s.stackMgr.GetStacks()) > 0 {
break
}
time.Sleep(time.Second)
}
s.recreateBootStaleApps()
s.ReconcileDriveGates()
t := time.NewTicker(30 * time.Second)