package service import ( "context" "errors" "fmt" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "git.nakama.town/fmartingr/gotoolkit/model" ) type Service struct { servers []model.Server cancel context.CancelFunc } func (s *Service) Start(ctx context.Context) error { ctx, cancel := context.WithCancel(ctx) s.cancel = cancel for _, server := range s.servers { if server.IsEnabled() { go func() { if err := server.Start(ctx); err != nil && !errors.Is(err, http.ErrServerClosed) { slog.Error("error starting server", slog.String("err", err.Error())) } }() } } return nil } func (s *Service) WaitStop(ctx context.Context) error { signals := make(chan os.Signal, 1) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) sig := <-signals slog.Debug("signal %s received, shutting down", slog.String("signal", fmt.Sprintf("%v", sig))) if err := s.Stop(ctx); err != nil { return err } return nil } func (s *Service) Stop(ctx context.Context) error { s.cancel() shuwdownContext, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() for _, server := range s.servers { if server.IsEnabled() { if err := server.Stop(shuwdownContext); err != nil && !errors.Is(err, http.ErrServerClosed) { slog.Error("error shutting down http server", slog.String("err", err.Error())) return err } } } return nil } func NewService(servers []model.Server) (*Service, error) { server := &Service{ servers: servers, } return server, nil }