diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index 0ae0af39..cdb368c4 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -642,6 +642,15 @@ func (app *App) Stop() error { finishedShutdown.Wait() } + // run stop callbacks now that the server shutdowns are complete + for name, s := range app.Servers { + for _, stopHook := range s.onStopFuncs { + if err := stopHook(ctx); err != nil { + app.logger.Error("server stop hook", zap.String("server", name), zap.Error(err)) + } + } + } + return nil } diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index 77af3136..9ea04acb 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -253,6 +253,7 @@ type Server struct { connStateFuncs []func(net.Conn, http.ConnState) connContextFuncs []func(ctx context.Context, c net.Conn) context.Context onShutdownFuncs []func() + onStopFuncs []func(context.Context) error // TODO: Experimental (Nov. 2023) } // ServeHTTP is the entry point for all HTTP requests. @@ -630,11 +631,18 @@ func (s *Server) RegisterConnContext(f func(ctx context.Context, c net.Conn) con s.connContextFuncs = append(s.connContextFuncs, f) } -// RegisterOnShutdown registers f to be invoked on server shutdown. +// RegisterOnShutdown registers f to be invoked when the server begins to shut down. func (s *Server) RegisterOnShutdown(f func()) { s.onShutdownFuncs = append(s.onShutdownFuncs, f) } +// RegisterOnStop registers f to be invoked after the server has shut down completely. +// +// EXPERIMENTAL: Subject to change or removal. +func (s *Server) RegisterOnStop(f func(context.Context) error) { + s.onStopFuncs = append(s.onStopFuncs, f) +} + // HTTPErrorConfig determines how to handle errors // from the HTTP handlers. type HTTPErrorConfig struct {