Refactor httpd functions
Signed-off-by: Jan Tytgat <jan.tytgat@corelayer.eu>
This commit is contained in:
@ -3,12 +3,14 @@ package httpd
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.flexabyte.io/flexabyte/go-slogd/slogd"
|
"git.flexabyte.io/flexabyte/go-kit/slogd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunHttpServer(ctx context.Context, log *slog.Logger, listenAddress string, port int, h http.Handler, shutdownTimeout time.Duration) error {
|
func RunHttpServer(ctx context.Context, log *slog.Logger, listenAddress string, port int, h http.Handler, shutdownTimeout time.Duration) error {
|
||||||
@ -16,39 +18,14 @@ func RunHttpServer(ctx context.Context, log *slog.Logger, listenAddress string,
|
|||||||
Addr: listenAddress + ":" + strconv.Itoa(port),
|
Addr: listenAddress + ":" + strconv.Itoa(port),
|
||||||
Handler: h}
|
Handler: h}
|
||||||
|
|
||||||
return run(ctx, s, log, shutdownTimeout)
|
log.LogAttrs(ctx, slogd.LevelTrace, "starting http server", slog.String("listenAddress", fmt.Sprintf("http://%s", s.Addr)))
|
||||||
}
|
|
||||||
|
|
||||||
func RunSocketHttpServer(ctx context.Context, log *slog.Logger, socketPath string, h http.Handler, shutdownTimeout time.Duration) error {
|
shutdownCtx, shutdownCancel := context.WithCancel(ctx)
|
||||||
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()
|
defer shutdownCancel()
|
||||||
|
|
||||||
log.LogAttrs(shutdownCtx, slogd.LevelTrace, "shutting down http server", slog.String("listenAddress", s.Addr))
|
// Run goroutine to handle graceful shutdown
|
||||||
// We received an interrupt signal, shut down.
|
idleConnectionsClosed := make(chan struct{})
|
||||||
if err := s.Shutdown(shutdownCtx); err != nil {
|
go shutdown(shutdownCtx, log, s, shutdownTimeout, idleConnectionsClosed)
|
||||||
// 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
|
var err error
|
||||||
if err = s.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
if err = s.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
||||||
@ -60,3 +37,54 @@ func run(ctx context.Context, s *http.Server, log *slog.Logger, shutdownTimeout
|
|||||||
<-idleConnectionsClosed
|
<-idleConnectionsClosed
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RunSocketHttpServer(ctx context.Context, log *slog.Logger, socketPath string, h http.Handler, shutdownTimeout time.Duration) error {
|
||||||
|
s := &http.Server{
|
||||||
|
Handler: h}
|
||||||
|
|
||||||
|
log.LogAttrs(ctx, slogd.LevelTrace, "starting http server", slog.String("socket", s.Addr))
|
||||||
|
|
||||||
|
shutdownCtx, shutdownCancel := context.WithCancel(ctx)
|
||||||
|
defer shutdownCancel()
|
||||||
|
|
||||||
|
// Run goroutine to handle graceful shutdown
|
||||||
|
idleConnectionsClosed := make(chan struct{})
|
||||||
|
go shutdown(shutdownCtx, log, s, shutdownTimeout, idleConnectionsClosed)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var config = new(net.ListenConfig)
|
||||||
|
var socket net.Listener
|
||||||
|
|
||||||
|
if socket, err = config.Listen(ctx, "unix", socketPath); err != nil {
|
||||||
|
log.LogAttrs(ctx, slogd.LevelError, "failed to listen on socket", slog.String("error", err.Error()))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = s.Serve(socket); err != nil && !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
|
||||||
|
}
|
||||||
|
|
||||||
|
func shutdown(ctx context.Context, log *slog.Logger, s *http.Server, shutdownTimeout time.Duration, idleConnectionsClosed chan struct{}) {
|
||||||
|
log.LogAttrs(ctx, slogd.LevelTrace, "awaiting shutdown signal for http server", slog.String("listenAddress", s.Addr))
|
||||||
|
<-ctx.Done()
|
||||||
|
|
||||||
|
// When shutdown signal is received, create a new context with the configured shutdown timeout
|
||||||
|
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||||
|
defer shutdownCancel()
|
||||||
|
|
||||||
|
log.LogAttrs(shutdownCtx, slogd.LevelTrace, "shutdown signal received for http server", slog.String("listenAddress", s.Addr))
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// 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, "shutdown for http server failed", slog.String("listenAddress", s.Addr), slog.Any("error", err))
|
||||||
|
}
|
||||||
|
log.LogAttrs(shutdownCtx, slogd.LevelTrace, "shutdown for http server completed", slog.String("listenAddress", s.Addr))
|
||||||
|
close(idleConnectionsClosed)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user