package server import ( "log" "net" "os" "os/signal" "strconv" "syscall" "time" "github.com/gofiber/fiber/v2" "git.pbiernat.dev/egommerce/api-entities/http" ) type ( Server struct { *fiber.App *Config addr string // e.g. "127.0.0.1:8080" PurgeFn } HeaderRequestID struct { RequestID string `reqHeader:"x-request-id"` } OptionFn func(*Server) error PurgeFn func() error ) func New(conf *Config) *Server { return &Server{ App: fiber.New(fiber.Config{ AppName: conf.AppID, ServerHeader: conf.AppName + ":" + conf.AppID, ReadTimeout: conf.ReadTimeout * time.Millisecond, WriteTimeout: conf.WriteTimeout * time.Millisecond, IdleTimeout: conf.IdleTimeout * time.Millisecond, }), Config: conf, addr: conf.NetAddr, } } func (s *Server) Start(while chan struct{}) error { go func() { sigint := make(chan os.Signal, 1) signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) <-sigint if err := s.PurgeFn(); err != nil { log.Fatalf("Failed to shutdown server. Reason: %v\n", err) } close(while) }() run := s.createRunFile("/app.run") // TODO move to common library (shared between server and worker) defer s.removeRunFile(run) ln, _ := net.Listen("tcp", s.addr) // ln = tls.NewListener(ln, s.App.Server().TLSConfig) err := s.Listener(ln) if err != nil { log.Fatalf("Failed to start server: %s. Reason: %v\n", s.Config.AppID, err) close(while) } <-while return err } func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { var hdr = new(HeaderRequestID) if err := c.ReqHeaderParser(hdr); err != nil { return "", err } return hdr.RequestID, nil } func (s *Server) Error(c *fiber.Ctx, code int, msg string) error { return c.Status(code).JSON(http.ErrorResponse{Error: msg}) } func (s *Server) createRunFile(path string) *os.File { run, err := os.Create(path) if err != nil { log.Fatalf("Failed to create run file. Reason: %v\n", err) os.Exit(1) } run.WriteString(strconv.Itoa(os.Getpid())) return run } func (s *Server) removeRunFile(f *os.File) error { return f.Close() }