http.go 1.4 KB

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