package app import ( "context" "errors" "go.uber.org/zap" "hub_admin_backend_service/internal/initialize" "hub_admin_backend_service/internal/server/http" "hub_admin_backend_service/pkg/closer" "time" ) func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error { defer func() { if r := recover(); r != nil { logger.Error("Recovered from a panic", zap.Any("error", r)) } }() logger.Info("Starting application", zap.String("AppName", cfg.AppName)) ctx, cancel := context.WithCancel(ctx) defer cancel() shutdownGroup := closer.NewCloserGroup() mdb, err := initialize.MongoDB(ctx, cfg) if err != nil { logger.Error("Failed to initialize MongoDB", zap.Error(err)) return err } repositories := initialize.NewRepository(initialize.RepositoryDeps{ Logger: logger, Mdb: mdb, }) controllers := initialize.NewControllers(initialize.ControllerDeps{ Logger: logger, Repos: repositories, }) internalSrv := http.NewServer(http.ServerConfig{ Logger: logger, Controllers: []http.Controller{controllers.PrivilegeInternal, controllers.TariffInternal}, }) externalSrv := http.NewServer(http.ServerConfig{ Logger: logger, Controllers: []http.Controller{controllers.PrivilegeExternal, controllers.TariffExternal}, }) go func() { if err := internalSrv.Start(cfg.InternalHttpAddress); err != nil { logger.Error("Server startup error", zap.Error(err)) cancel() } }() go func() { if err := externalSrv.Start(cfg.ExternalHttpAddress); err != nil { logger.Error("Server startup error", zap.Error(err)) cancel() } }() internalSrv.ListRoutes() externalSrv.ListRoutes() shutdownGroup.Add(closer.CloserFunc(internalSrv.Shutdown)) shutdownGroup.Add(closer.CloserFunc(externalSrv.Shutdown)) shutdownGroup.Add(closer.CloserFunc(mdb.Client().Disconnect)) <-ctx.Done() timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 10*time.Second) defer timeoutCancel() if err := shutdownGroup.Call(timeoutCtx); err != nil { if errors.Is(err, context.DeadlineExceeded) { logger.Error("Shutdown timed out", zap.Error(err)) } else { logger.Error("Failed to shutdown services gracefully", zap.Error(err)) } return err } logger.Info("Application has stopped") return nil }