From e9eed3ddc4229db707cccb30beddde15044eff16 Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Fri, 24 May 2024 18:31:56 +0200 Subject: refactor: split server cmd and module It should now be possible to run the server from inside another go application by importing the main module and running its Start() function --- internal/server/server.go | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'internal/server/server.go') diff --git a/internal/server/server.go b/internal/server/server.go index 6c4b732..262e9a7 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -2,7 +2,6 @@ package server import ( "context" - "log" "log/slog" "net" "net/http" @@ -15,7 +14,9 @@ import ( ) type Server struct { - *http.Server + cfg *config.Config + server *http.Server + listener net.Listener } func New(conf *config.Config, index *index.ReadIndex, liveReload bool) (*Server, error) { @@ -23,11 +24,10 @@ func New(conf *config.Config, index *index.ReadIndex, liveReload bool) (*Server, if err != nil { return nil, err } - listenAddress := net.JoinHostPort(conf.Web.ListenAddress, strconv.Itoa(conf.Web.Port)) return &Server{ - &http.Server{ - Addr: listenAddress, + cfg: conf, + server: &http.Server{ Handler: mux, ReadHeaderTimeout: 20 * time.Second, }, @@ -35,7 +35,27 @@ func New(conf *config.Config, index *index.ReadIndex, liveReload bool) (*Server, } func (s *Server) Start() error { - if err := s.ListenAndServe(); err != http.ErrServerClosed { + listenAddress := net.JoinHostPort(s.cfg.Web.ListenAddress, strconv.Itoa(s.cfg.Web.Port)) + l, err := net.Listen("tcp", listenAddress) + if err != nil { + return errors.WithMessagef( + err, + "could not listen on address %s and port %d", + s.cfg.Web.ListenAddress, + s.cfg.Web.Port, + ) + } + s.listener = l + + if s.cfg.Web.Environment == "development" { + slog.Info( + "server listening on", + "url", + s.cfg.Web.BaseURL.String(), + ) + } + + if err := s.server.Serve(l); err != nil && err != http.ErrServerClosed { return errors.WithMessage(err, "could not start server") } @@ -51,12 +71,13 @@ func (s *Server) Stop() chan struct{} { slog.Debug("shutting down server") ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - err := s.Server.Shutdown(ctx) + err := s.server.Shutdown(ctx) slog.Debug("server shut down") if err != nil { // Error from closing listeners, or context timeout: - log.Printf("HTTP server Shutdown: %v", err) + slog.Error("error shutting down server", "error", err) } + s.listener.Close() close(idleConnsClosed) }() -- cgit 1.4.1