package app import ( "context" "fmt" "time" "go.uber.org/zap" "penahub.gitlab.yandexcloud.net/external/treasurer/internal/initialize" "penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/swagger" "penahub.gitlab.yandexcloud.net/external/treasurer/internal/models" "penahub.gitlab.yandexcloud.net/external/treasurer/internal/server" "penahub.gitlab.yandexcloud.net/external/treasurer/internal/worker" "penahub.gitlab.yandexcloud.net/external/treasurer/pkg/closer" "penahub.gitlab.yandexcloud.net/external/treasurer/pkg/mongo" ) const ( shutdownTimeout = 5 * time.Second ) func Run(ctx context.Context, config *models.Config, logger *zap.Logger) error { mongoDB, connectionErr := mongo.Connect(ctx, &mongo.ConnectDeps{ Configuration: &config.Database, Timeout: 10 * time.Second, }) if connectionErr != nil { return fmt.Errorf("failed connection to db: %w", connectionErr) } closer := closer.New() openapi, swaggerErr := swagger.GetSwagger() if swaggerErr != nil { return fmt.Errorf("failed to loading openapi spec: %w", swaggerErr) } repositories, err := initialize.NewRepositories(initialize.RepositoriesDeps{ Logger: logger, Database: mongoDB, }) if err != nil { return err.Wrap("failed to initialize repositories") } clients, err := initialize.NewClients(initialize.ClientsDeps{ Logger: logger, YoomoneyConfiguration: &config.Service.YoomomeyConfiguration, }) if err != nil { return err.Wrap("failed to initialize clients") } services, err := initialize.NewServices(initialize.ServicesDeps{ Logger: logger, Repositories: *repositories, Clients: *clients, ConfigurationHTTP: &config.HTTP, }) if err != nil { return err.Wrap("failed to initialize services") } workers, err := initialize.NewWorkers(initialize.WorkersDeps{ Logger: logger, Services: *services, }) if err != nil { return err.Wrap("failed to initialize workers") } controllers, err := initialize.NewControllers(initialize.ControllersDeps{ Logger: logger, Services: *services, }) if err != nil { return err.Wrap("failed to initialize controllers") } api, err := initialize.NewAPI(controllers) if err != nil { return err.Wrap("failed to initialize api") } httpServer, err := server.NewHTTP(server.DepsHTTP{ Logger: logger, Swagger: openapi, }) if err != nil { return err.Wrap("failed to initialize http server") } httpServer.Register(api) grpcServer, err := server.NewGRPC(server.DepsGRPC{ Logger: logger, }) if err != nil { return err.Wrap("failed to initialize grpc server") } grpcServer.Register(controllers.PaymentGRPC) go httpServer.Run(&config.HTTP) go grpcServer.Run(&config.GRPC) go worker.Run(ctx, workers) closer.Add(mongoDB.Client().Disconnect) closer.Add(httpServer.Stop) closer.Add(grpcServer.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 }