85 lines
1.6 KiB
Go
85 lines
1.6 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
const (
|
|
ServerShutdownTimeout = 10 * time.Second
|
|
ServerReadTimeout = 5 * time.Second
|
|
)
|
|
|
|
type Handler struct {
|
|
url string
|
|
fnHandle func(http.ResponseWriter, *http.Request)
|
|
}
|
|
|
|
func NewHandler(url string, fnHandle func(http.ResponseWriter, *http.Request)) Handler {
|
|
return Handler{url: url, fnHandle: fnHandle}
|
|
}
|
|
|
|
type Server struct {
|
|
*http.Server
|
|
|
|
ctx context.Context
|
|
}
|
|
|
|
type ServerOption func()
|
|
|
|
func NewServer(ctx context.Context, port int, handlers ...Handler) Server {
|
|
srvmux := http.NewServeMux()
|
|
for _, h := range handlers {
|
|
srvmux.HandleFunc(h.url, h.fnHandle)
|
|
}
|
|
srv := http.Server{
|
|
Addr: ":" + strconv.Itoa(port),
|
|
Handler: srvmux,
|
|
ReadTimeout: ServerReadTimeout,
|
|
}
|
|
|
|
server := Server{
|
|
Server: &srv,
|
|
ctx: ctx,
|
|
}
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
if err := server.Stop(); err != nil {
|
|
log.Err(err).Msg("unable to stop the server correctly")
|
|
}
|
|
}()
|
|
|
|
return server
|
|
}
|
|
|
|
func (srv *Server) Serve() {
|
|
log.Info().Str("addr", srv.Addr).Msg("http server listening")
|
|
|
|
if err := srv.ListenAndServe(); err != nil {
|
|
if !errors.Is(err, http.ErrServerClosed) {
|
|
log.Err(err).Msg("error occurred while serving server")
|
|
return
|
|
}
|
|
log.Info().Msg("server stopped")
|
|
}
|
|
}
|
|
|
|
func (srv *Server) Stop() error {
|
|
log.Info().Msg("stopping server...")
|
|
|
|
shutdownCtx, fnCancel := context.WithTimeout(srv.ctx, ServerShutdownTimeout)
|
|
defer fnCancel()
|
|
|
|
return srv.Shutdown(shutdownCtx)
|
|
}
|
|
|
|
func (srv *Server) Done() <-chan struct{} {
|
|
return srv.ctx.Done()
|
|
}
|