feat(report): v0.139.0 — immediate out-of-cycle hub report on user actions (Direction 1)
New report.Trigger (buffered-1 chan + worker; quiet 2s, min spacing 15s, trailing-edge coalescing) generalizes the v0.70.0 geo out-of-band push. One canonical fire closure in main.go; wired: geo save/sync + app deploy/remove/delete (api reportPushNow), escrow recovery-code claim, notification-prefs save, app-email toggle, offsite config + per-app toggle, customer claim (web SetReportTrigger seam, nil-safe, fired only after a successful local commit). 15-min hub-report cycle untouched as the reconciliation backbone; hub.enabled=false stays a strict no-op. Tests: trigger engine (2 red-proofs), seam fires-after-commit-only, nil-seam no-ops.
This commit is contained in:
@@ -795,20 +795,30 @@ func main() {
|
||||
alertMgr.Refresh(report, cfg, backupMgr, false, "")
|
||||
}()
|
||||
|
||||
// --- Out-of-cycle report trigger (v0.139.0, Direction 1) ---
|
||||
// ONE canonical fire closure (full BuildReport + Claimed + Push) behind a debounced,
|
||||
// coalescing trigger — user actions with hub-side effects (geo, escrow claim, settings
|
||||
// save, offsite toggle, app deploy/remove, customer claim) round-trip in seconds instead
|
||||
// of the next ~15-min cycle. The scheduled hub-report job above stays the reconciliation
|
||||
// backbone; the trigger is best-effort on top (its failures degrade to the cycle).
|
||||
// nil when hub reporting is off → the api/web seams stay unset (strict no-op).
|
||||
var reportTrigger *report.Trigger
|
||||
if hubPusher != nil && cfg.Hub.Enabled {
|
||||
fireReport := func() error {
|
||||
rep := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), logger)
|
||||
rep.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
|
||||
return hubPusher.Push(rep)
|
||||
}
|
||||
reportTrigger = report.NewTrigger(fireReport, logger)
|
||||
go reportTrigger.Run(ctx)
|
||||
}
|
||||
|
||||
// --- Initialize API router ---
|
||||
apiRouter := api.NewRouter(cfg, *configPath, sett, stackMgr, syncer, cpuCollector, backupMgr, metricsStore, updater, notifier, logger)
|
||||
if hubPusher != nil {
|
||||
// Out-of-band, non-blocking hub report push (e.g. after a geo settings change) so
|
||||
if reportTrigger != nil {
|
||||
// Out-of-cycle, non-blocking hub report push (geo changes + app deploy/remove) so
|
||||
// the hub reflects the new state immediately instead of after the next ~15-min cycle.
|
||||
apiRouter.SetReportPushTrigger(func() {
|
||||
go func() {
|
||||
rep := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), logger)
|
||||
rep.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
|
||||
if err := hubPusher.Push(rep); err != nil {
|
||||
logger.Printf("[WARN] [report] Out-of-band geo report push failed: %v", err)
|
||||
}
|
||||
}()
|
||||
})
|
||||
apiRouter.SetReportPushTrigger(reportTrigger.Fire)
|
||||
}
|
||||
if assetsSyncer != nil {
|
||||
apiRouter.SetAssetsSyncer(assetsSyncer)
|
||||
@@ -883,6 +893,12 @@ func main() {
|
||||
webServer.SetEscrowStale(escrowConfirmer.StaleBlob)
|
||||
}
|
||||
webServer.SetIntegrationManager(integrationMgr)
|
||||
if reportTrigger != nil {
|
||||
// Out-of-cycle report push after hub-relevant user actions (escrow claim, settings
|
||||
// save, offsite config/toggle, customer claim) — same debounced trigger as the api
|
||||
// router's; nil (hub reporting off) leaves the seam a strict no-op.
|
||||
webServer.SetReportTrigger(reportTrigger.Fire)
|
||||
}
|
||||
if quiesceLoop != nil {
|
||||
webServer.SetBackupTrigger(quiesceLoop) // "Mentés most" → app-consistent backup via the quiesce loop
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user