package app import ( "context" "github.com/jackc/pgx/v5/pgxpool" "merch-api/config" "merch-api/internal/merch" "merch-api/internal/user" "merch-api/pkg/dbase" "merch-api/pkg/router" "merch-api/pkg/utils" "time" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" ) const pkgLogHeader string = "Application |" type App struct { cfg config.Config router *router.Router modules []Module dbPool *pgxpool.Pool } func New(ctx context.Context, cfg config.Config) *App { //providers r := router.NewRouter(router.Deps{ Host: cfg.Http.Host, Port: cfg.Http.Port, Prefix: cfg.Http.Prefix, GinMode: cfg.Http.GinMode, }) dbPool, err := dbase.ConnectPool(ctx, dbase.Deps{ Host: cfg.DBase.Host, Port: cfg.DBase.Port, Username: cfg.DBase.Username, Password: cfg.DBase.Password, DBName: cfg.DBase.DBName, }) u := utils.New() userProv := user.New(user.Deps{ DB: dbPool, Utils: u, }) if err != nil { log.WithError(err).Fatalf("%v failed to connect database", pkgLogHeader) } //modules var modules []Module m := merch.New(merch.Deps{ DB: dbPool, Utils: u, UserProvider: userProv, }) modules = append(modules, m) return &App{ cfg: cfg, router: r, modules: modules, dbPool: dbPool, } } func (app *App) Run(ctx context.Context) error { log.Infof("%v starting...", pkgLogHeader) baseGroup := app.router.BaseGroup() app.collectRoutes(baseGroup) errCh := make(chan error, 10) go func() { if err := app.router.Run(); err != nil { errCh <- err } }() select { case <-ctx.Done(): app.shutdown(ctx) case err := <-errCh: return err } return nil } func (app *App) shutdown(ctx context.Context) { log.Infof("%v shutting down...", pkgLogHeader) shutdownCtx, shutdownCancel := context.WithTimeout(ctx, 15*time.Second) defer shutdownCancel() app.dbPool.Close() if err := app.router.Shutdown(shutdownCtx); err != nil { log.WithError(err).Warnf("%v error shutting down application", pkgLogHeader) } log.Infof("%v shutdown complete", pkgLogHeader) } func (app *App) collectRoutes(group *gin.RouterGroup) { for _, m := range app.modules { m.RegisterRoutes(group) } log.Infof("%v routes registered", pkgLogHeader) }