package app import ( "context" "fmt" "time" "go.uber.org/zap" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/server" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/swagger" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils" "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/closer" "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/mongo" ) const ( shutdownTimeout = 5 * time.Second ) func Run(ctx context.Context, config *models.Config, logger *zap.Logger) error { mongoDB, err := mongo.Connect(ctx, &mongo.ConnectDeps{ Configuration: &config.Database, Timeout: 10 * time.Second, }) if err != nil { return fmt.Errorf("failed connection to db: %w", err) } clients := initialize.NewClients(&initialize.ClientsDeps{ Logger: logger, AuthURL: &config.Service.AuthMicroservice.URL, HubadminURL: &config.Service.HubadminMicroservice.URL, }) repositories := initialize.NewRepositories(&initialize.RepositoriesDeps{ Logger: logger, MongoDB: mongoDB, }) services := initialize.NewServices(&initialize.ServicesDeps{ Logger: logger, Repositories: repositories, Clients: clients, }) controllers := initialize.NewControllers(&initialize.ControllersDeps{ Logger: logger, Services: services, }) openapi, err := swagger.GetSwagger() if err != nil { return fmt.Errorf("failed to loading openapi spec: %w", err) } api := initialize.NewAPI(controllers) closer := closer.New() httpServer := server.New(&server.Deps{ Logger: logger, Swagger: openapi, AuthenticationFunc: utils.NewAuthenticator(utils.NewJWT(&config.Service.JWT)), }) httpServer.Register(api) go httpServer.Run(&config.HTTP) closer.Add(mongoDB.Client().Disconnect) closer.Add(httpServer.Stop) <-ctx.Done() logger.Info("shutting down app gracefully") shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) defer cancel() if err := closer.Close(shutdownCtx); err != nil { return fmt.Errorf("closer: %w", err) } return nil }