http.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package http
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "github.com/gin-gonic/gin"
  7. "github.com/go-nunu/nunu-layout-advanced/pkg/log"
  8. "net/http"
  9. "time"
  10. )
  11. type Server struct {
  12. *gin.Engine
  13. httpSrv *http.Server
  14. host string
  15. port int
  16. logger *log.Logger
  17. }
  18. type Option func(s *Server)
  19. func NewServer(engine *gin.Engine, logger *log.Logger, opts ...Option) *Server {
  20. s := &Server{
  21. Engine: engine,
  22. logger: logger,
  23. }
  24. for _, opt := range opts {
  25. opt(s)
  26. }
  27. return s
  28. }
  29. func WithServerHost(host string) Option {
  30. return func(s *Server) {
  31. s.host = host
  32. }
  33. }
  34. func WithServerPort(port int) Option {
  35. return func(s *Server) {
  36. s.port = port
  37. }
  38. }
  39. func (s *Server) Start(ctx context.Context) error {
  40. s.httpSrv = &http.Server{
  41. Addr: fmt.Sprintf("%s:%d", s.host, s.port),
  42. Handler: s,
  43. }
  44. if err := s.httpSrv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
  45. s.logger.Sugar().Fatalf("listen: %s\n", err)
  46. }
  47. return nil
  48. }
  49. func (s *Server) Stop(ctx context.Context) error {
  50. s.logger.Sugar().Info("Shutting down server...")
  51. // The context is used to inform the server it has 5 seconds to finish
  52. // the request it is currently handling
  53. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  54. defer cancel()
  55. if err := s.httpSrv.Shutdown(ctx); err != nil {
  56. s.logger.Sugar().Fatal("Server forced to shutdown: ", err)
  57. }
  58. s.logger.Sugar().Info("Server exiting")
  59. return nil
  60. }