init repo
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const (
|
||||
ServerShutdownTimeout = 10 * time.Second
|
||||
ServerReadTimeout = 5 * time.Second
|
||||
DefaultPort = 8888
|
||||
)
|
||||
|
||||
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 {
|
||||
if port == 0 {
|
||||
log.Warn().Int("port", DefaultPort).Msg("no port detected, set to default")
|
||||
port = DefaultPort
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
Reference in New Issue
Block a user