From 523c48d1d9c5165936b8d6ad216b79140294b14c Mon Sep 17 00:00:00 2001 From: Denis Mishankov Date: Sun, 2 Nov 2025 00:49:02 +0300 Subject: [PATCH] Handle graceful shutdown via context in Application Move signal handling from HTTPServer to Application level Use context for shutdown coordination across components HTTPServer now listens for context cancellation instead of signals directly --- application/application.go | 5 +++++ httpserver/httpserver.go | 16 ++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/application/application.go b/application/application.go index 8eea018..3f2d307 100644 --- a/application/application.go +++ b/application/application.go @@ -3,6 +3,8 @@ package application import ( "context" "fmt" + "os" + "os/signal" "sync" "time" @@ -92,6 +94,9 @@ func (a *Application) Run(ctx context.Context) error { ctx = context.Background() } + ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, os.Kill) + defer cancel() + log.InfoContext(ctx, "starting application", "startupTasks", len(a.startupTasks)) for dbName, db := range a.databases { diff --git a/httpserver/httpserver.go b/httpserver/httpserver.go index 49232a8..77fd554 100644 --- a/httpserver/httpserver.go +++ b/httpserver/httpserver.go @@ -6,9 +6,6 @@ import ( "errors" "fmt" "net/http" - "os" - "os/signal" - "syscall" "time" "github.com/mishankov/platforma/log" @@ -42,20 +39,19 @@ func (s *HTTPServer) Run(ctx context.Context) error { if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) { log.ErrorContext(ctx, "HTTP server error", "error", err) } - log.InfoContext(ctx, "stopped serving new connections.") + log.InfoContext(ctx, "stopped serving new connections") }() - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) - <-sigChan + <-ctx.Done() - shutdownCtx, shutdownRelease := context.WithTimeout(ctx, s.shutdownTimeout) - defer shutdownRelease() + shutdownCtx := context.Background() + shutdownCtx, cancel := context.WithTimeout(shutdownCtx, s.shutdownTimeout) + defer cancel() if err := server.Shutdown(shutdownCtx); err != nil { return fmt.Errorf("failed to gracefully shutdown HTTP server: %w", err) } - log.InfoContext(ctx, "graceful shutdown completed.") + log.InfoContext(ctx, "graceful shutdown completed") return nil }