From 19304a8d8ea396225a972dbb5e3b6e6bb6b5f164 Mon Sep 17 00:00:00 2001 From: Jan Tytgat Date: Tue, 29 Apr 2025 14:46:32 +0200 Subject: [PATCH] Initial functions for http servers Signed-off-by: Jan Tytgat --- httpd/httpd.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 httpd/httpd.go diff --git a/httpd/httpd.go b/httpd/httpd.go new file mode 100644 index 0000000..6bfe57f --- /dev/null +++ b/httpd/httpd.go @@ -0,0 +1,62 @@ +package httpd + +import ( + "context" + "errors" + "log/slog" + "net/http" + "strconv" + "time" + + "git.flexabyte.io/flexabyte/go-slogd/slogd" +) + +func RunHttpServer(ctx context.Context, log *slog.Logger, listenAddress string, port int, h http.Handler, shutdownTimeout time.Duration) error { + s := &http.Server{ + Addr: listenAddress + ":" + strconv.Itoa(port), + Handler: h} + + return run(ctx, s, log, shutdownTimeout) +} + +func RunSocketHttpServer(ctx context.Context, log *slog.Logger, socketPath string, h http.Handler, shutdownTimeout time.Duration) error { + s := &http.Server{ + Handler: h} + + return run(ctx, s, log, shutdownTimeout) +} + +func run(ctx context.Context, s *http.Server, log *slog.Logger, shutdownTimeout time.Duration) error { + log.LogAttrs(ctx, slogd.LevelTrace, "starting http server", slog.String("listenAddress", s.Addr)) + idleConnectionsClosed := make(chan struct{}) + + runCtx, runCancel := context.WithCancel(ctx) + defer runCancel() + + go func(ctx context.Context) { + log.LogAttrs(ctx, slogd.LevelTrace, "awaiting shutdown signal for http server", slog.String("listenAddress", s.Addr)) + <-ctx.Done() + + shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), shutdownTimeout) + defer shutdownCancel() + + log.LogAttrs(shutdownCtx, slogd.LevelTrace, "shutting down http server", slog.String("listenAddress", s.Addr)) + // We received an interrupt signal, shut down. + if err := s.Shutdown(shutdownCtx); err != nil { + // Error from closing listeners, or context timeout: + log.LogAttrs(ctx, slogd.LevelTrace, "shutting down http server failed", slog.String("listenAddress", s.Addr), slog.Any("error", err)) + } + log.LogAttrs(shutdownCtx, slogd.LevelTrace, "shutting down http server completed", slog.String("listenAddress", s.Addr)) + close(idleConnectionsClosed) + }(runCtx) + + var err error + if err = s.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) { + // Error starting or closing listener: + log.LogAttrs(ctx, slogd.LevelError, "http server start failed", slog.String("error", err.Error())) + return err + } + + <-idleConnectionsClosed + return err +}