gocommon/webserver/webserver.go
Matthieu 'JP' DERASSE a7b1989231
All checks were successful
continuous-integration/drone/push Build is passing
fix(webserver): always panic in case of an issue in webserver
2023-08-13 12:16:27 +00:00

73 lines
1.6 KiB
Go

package webserver
import (
"context"
"errors"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
const defaultTimeout = 90 * time.Second
const defaultShutdownTimeout = 10 * time.Second
type cleanupFunc func() error
// ExecuteServerParams are the parameters expected in the ExecuteServer function.
type ExecuteServerParams struct {
Cleanup cleanupFunc
ShutdownTimeout *time.Duration
}
// ExecuteServer will launche a http.Server and handle the "exit" signals and gracefully stop the server
// and call the cleanup function.
func ExecuteServer(ctx context.Context, srv *http.Server, params *ExecuteServerParams) {
if srv == nil {
log.Panicf("missing http.server params")
return
}
if srv.ReadTimeout == 0 {
srv.ReadTimeout = defaultTimeout
}
if srv.WriteTimeout == 0 {
srv.WriteTimeout = defaultTimeout
}
log.Printf("launching webserver on %s", srv.Addr)
go func() {
if err := srv.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
log.Panicf("HTTP server error: %v", err)
return
}
log.Printf("Stopped serving new connections.")
}()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
shutdownCtx, shutdownRelease := context.WithTimeout(ctx, defaultShutdownTimeout)
defer shutdownRelease()
if err := srv.Shutdown(shutdownCtx); err != nil {
log.Panicf("HTTP shutdown error: %v", err)
return
}
if params != nil && params.Cleanup != nil {
if err := params.Cleanup(); err != nil {
log.Panicf("Impossible to cleanup correctly after shutdown. error : %v", err)
return
}
}
log.Print("Graceful shutdown complete.")
}