about summary refs log tree commit diff stats
path: root/internal/server
diff options
context:
space:
mode:
authorAlan Pearce2024-05-24 18:31:56 +0200
committerAlan Pearce2024-05-24 18:31:56 +0200
commite9eed3ddc4229db707cccb30beddde15044eff16 (patch)
treec586eae45a4aa99fd1a971c2bd29ad2e74d14975 /internal/server
parent2c1491de56d0c3e2f4cb0b0c1e33035510f72fc5 (diff)
downloadsearchix-e9eed3ddc4229db707cccb30beddde15044eff16.tar.lz
searchix-e9eed3ddc4229db707cccb30beddde15044eff16.tar.zst
searchix-e9eed3ddc4229db707cccb30beddde15044eff16.zip
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
Diffstat (limited to 'internal/server')
-rw-r--r--internal/server/server.go37
1 files changed, 29 insertions, 8 deletions
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)
 	}()