v0.15.5: Fix startup hub report — Push() returns real errors, startup retries 3x with 15s delay

This commit is contained in:
2026-02-19 10:08:43 +01:00
parent 925711e44e
commit 00c668fc92
3 changed files with 25 additions and 9 deletions
+9
View File
@@ -1,5 +1,14 @@
## Changelog ## Changelog
### What was just completed (2026-02-19 session 55)
- **v0.15.5 — Fix startup hub report silently failing:**
`Push()` now returns actual errors instead of always `nil`. Previously, push failures were logged internally but the caller could never detect them, leading to a misleading `[INFO] Startup hub report sent` log even when the push actually failed (e.g., hub returning HTTP 503 during simultaneous deployment). Removed the "Never returns error to caller" behavior: marshal error returns a wrapped error, and after 3 failed retries the error is returned to the caller (the internal `[WARN]` log before `return nil` is gone).
Startup hub push now retries 3 times with 15-second delays between outer attempts, giving the hub time to come up when both are deployed together. Each outer attempt uses `Push()`'s own internal 3-retry logic (5s backoff), so the hub gets up to ~40s total to become ready. If all 3 outer attempts fail, logs a clear warning with the next scheduled push interval.
**Files modified (2):** `internal/report/pusher.go`, `cmd/controller/main.go`
### What was just completed (2026-02-19 session 54) ### What was just completed (2026-02-19 session 54)
- **v0.15.4 (controller) + hub v0.1.6 — Hub reporting improvements:** - **v0.15.4 (controller) + hub v0.1.6 — Hub reporting improvements:**
+14 -4
View File
@@ -290,10 +290,20 @@ func main() {
if hubPusher != nil { if hubPusher != nil {
if cfg.Hub.Enabled { if cfg.Hub.Enabled {
r := report.BuildReport(cfg, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths()) r := report.BuildReport(cfg, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths())
if err := hubPusher.Push(r); err != nil { var pushErr error
logger.Printf("[WARN] Startup hub report failed: %v", err) for attempt := 1; attempt <= 3; attempt++ {
} else { pushErr = hubPusher.Push(r)
logger.Println("[INFO] Startup hub report sent") if pushErr == nil {
logger.Println("[INFO] Startup hub report sent")
break
}
logger.Printf("[WARN] Startup hub report attempt %d/3 failed: %v", attempt, pushErr)
if attempt < 3 {
time.Sleep(15 * time.Second)
}
}
if pushErr != nil {
logger.Printf("[WARN] Startup hub report failed after 3 attempts — next scheduled push in %s", cfg.Hub.PushInterval)
} }
} else { } else {
// Send a minimal "disabled" notification so hub knows reporting is intentionally off // Send a minimal "disabled" notification so hub knows reporting is intentionally off
+2 -5
View File
@@ -36,7 +36,6 @@ func NewPusher(cfg *config.HubConfig, logger *log.Logger) *Pusher {
} }
// Push sends a report to the hub. Retries 3 times with 5s backoff. // Push sends a report to the hub. Retries 3 times with 5s backoff.
// Never returns error to caller — push failures should not affect controller operation.
func (p *Pusher) Push(report *Report) error { func (p *Pusher) Push(report *Report) error {
if !p.enabled { if !p.enabled {
return nil return nil
@@ -44,8 +43,7 @@ func (p *Pusher) Push(report *Report) error {
data, err := json.Marshal(report) data, err := json.Marshal(report)
if err != nil { if err != nil {
p.logger.Printf("[WARN] Hub report marshal failed: %v", err) return fmt.Errorf("marshal report: %w", err)
return nil
} }
url := p.hubURL + "/api/v1/report" url := p.hubURL + "/api/v1/report"
@@ -81,8 +79,7 @@ func (p *Pusher) Push(report *Report) error {
lastErr = fmt.Errorf("HTTP %d", resp.StatusCode) lastErr = fmt.Errorf("HTTP %d", resp.StatusCode)
} }
p.logger.Printf("[WARN] Hub report push failed after 3 attempts: %v", lastErr) return fmt.Errorf("hub push failed after 3 attempts: %w", lastErr)
return nil
} }
// PushOnce sends a single report regardless of the enabled flag. // PushOnce sends a single report regardless of the enabled flag.