From 752c15009b0d97fcaf2dbb40460cd8167ecc391f Mon Sep 17 00:00:00 2001 From: Fuwn Date: Wed, 21 Jan 2026 06:21:55 -0800 Subject: perf: Implement zero-downtime configuration reload --- cmd/kaze/main.go | 46 ++++++---------------------------------------- 1 file changed, 6 insertions(+), 40 deletions(-) (limited to 'cmd') diff --git a/cmd/kaze/main.go b/cmd/kaze/main.go index f9e9cd4..e010223 100644 --- a/cmd/kaze/main.go +++ b/cmd/kaze/main.go @@ -132,7 +132,7 @@ func main() { logger.Info("kaze is running", "address", fmt.Sprintf("http://%s:%d", cfg.Server.Host, cfg.Server.Port)) - // Reload function (returns error for API endpoint) + // Reload function for API endpoint and SIGHUP - performs zero-downtime reload var reloadConfig func() error reloadConfig = func() error { logger.Info("reloading configuration...") @@ -153,11 +153,8 @@ func main() { sched.Stop() logger.Debug("stopped scheduler") - // Update config reference - cfg = newCfg - // Create new scheduler with updated config - newSched, err := monitor.NewScheduler(cfg, store, logger, *configPath) + newSched, err := monitor.NewScheduler(newCfg, store, logger, *configPath) if err != nil { logger.Error("failed to create new scheduler", "error", err) // Restart old scheduler @@ -165,44 +162,13 @@ func main() { return fmt.Errorf("failed to create new scheduler: %w", err) } - // Replace scheduler + // Swap config/scheduler without restarting the HTTP listener + srv.UpdateConfig(newCfg, newSched) + cfg = newCfg sched = newSched sched.Start() - // Stop old server - shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second) - if err := srv.Stop(shutdownCtx); err != nil { - logger.Error("error stopping old server", "error", err) - } - shutdownCancel() - - // Create new server with updated config - newSrv, err := server.New(cfg, store, sched, logger) - if err != nil { - logger.Error("failed to create new server", "error", err) - // Try to restart old server - go func() { - if err := srv.Start(); err != nil { - logger.Error("server error", "error", err) - } - }() - return fmt.Errorf("failed to create new server: %w", err) - } - - // Replace server and set reload func and version on new server - srv = newSrv - srv.SetVersion(version, commit, date) - srv.SetReloadFunc(reloadConfig) - - // Start new server - go func() { - if err := srv.Start(); err != nil { - logger.Error("server error", "error", err) - cancel() - } - }() - - logger.Info("configuration reloaded successfully", + logger.Info("configuration reloaded successfully (zero-downtime)", "groups", len(cfg.Groups), "incidents", len(cfg.Incidents)) -- cgit v1.2.3