package server import ( "context" "fmt" "net/http" "os" "os/signal" "syscall" "time" "github.com/gorilla/mux" "github.com/sirupsen/logrus" ) type Server struct { host string port int handler http.Handler log *logrus.Logger } func NewServer(host string, port int, handler http.Handler, log *logrus.Logger) *Server { return &Server{ host: host, port: port, handler: handler, log: log, } } func (s *Server) Start() error { router := mux.NewRouter() router.Handle("/api", s.handler).Methods("GET") router.Handle("/api/{filename:.+.md}", s.handler) router.PathPrefix("/").Handler(http.FileServer(http.Dir("frontend/dist"))) srv := &http.Server{ Addr: fmt.Sprintf("%s:%d", s.host, s.port), Handler: router, } // Start server go func() { s.log.Infof("Server listening on %s:%d", s.host, s.port) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { s.log.Errorf("Server error: %v", err) } }() // Wait for interrupt signal quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit s.log.Info("Shutting down server...") // Create context with timeout ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Shutdown server if err := srv.Shutdown(ctx); err != nil { s.log.Errorf("Server shutdown error: %v", err) return err } s.log.Info("Server stopped") return nil }