codeword/internal/app/app.go

146 lines
4.2 KiB
Go
Raw Normal View History

2023-12-29 11:30:20 +00:00
package app
import (
2024-01-11 18:20:33 +00:00
"codeword/internal/controller/promocode"
"codeword/internal/controller/recovery"
2023-12-29 11:30:20 +00:00
"codeword/internal/initialize"
"codeword/internal/repository"
httpserver "codeword/internal/server/http"
"codeword/internal/services"
2024-01-05 11:37:06 +00:00
"codeword/internal/worker/purge_worker"
2024-01-01 14:13:54 +00:00
"codeword/internal/worker/recovery_worker"
2024-01-16 15:10:16 +00:00
"codeword/pkg/closer"
2023-12-29 11:30:20 +00:00
"context"
2024-01-16 15:10:16 +00:00
"errors"
2024-02-25 12:02:15 +00:00
"github.com/twmb/franz-go/pkg/kgo"
2023-12-29 11:30:20 +00:00
"go.uber.org/zap"
2024-01-16 15:10:16 +00:00
"time"
2023-12-29 11:30:20 +00:00
)
func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
2024-01-15 20:21:16 +00:00
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))
2023-12-29 11:30:20 +00:00
2024-01-15 08:43:55 +00:00
ctx, cancel := context.WithCancel(ctx)
defer cancel()
2024-01-16 15:10:16 +00:00
shutdownGroup := closer.NewCloserGroup()
2024-01-11 12:07:17 +00:00
mdb, err := initialize.MongoDB(ctx, cfg)
2023-12-29 12:41:26 +00:00
if err != nil {
logger.Error("Failed to initialize MongoDB", zap.Error(err))
2024-01-15 20:21:16 +00:00
return err
2023-12-29 12:41:26 +00:00
}
2024-01-15 13:32:46 +00:00
if err = initialize.InitDatabaseIndexes(ctx, mdb, logger); err != nil {
logger.Error("Failed to initialize db indexes", zap.Error(err))
return err
}
2024-02-25 12:02:15 +00:00
kafkaTariffClient, err := kgo.NewClient(
kgo.SeedBrokers(cfg.KafkaBrokers),
kgo.ConsumeResetOffset(kgo.NewOffset().AtStart()),
kgo.DefaultProduceTopic(cfg.KafkaTopic),
)
if err != nil {
return err
}
discountRpcClient, err := initialize.DiscountGRPCClient(cfg.DiscountServiceAddress)
if err != nil {
logger.Error("failed to connect to discount service", zap.Error(err))
return err
}
brokers := initialize.NewBrokers(initialize.BrokersDeps{
Logger: logger,
TariffClient: kafkaTariffClient,
Topic: cfg.KafkaTopic,
})
2024-01-17 13:51:42 +00:00
2024-01-11 12:07:17 +00:00
rdb, err := initialize.Redis(ctx, cfg)
encrypt := initialize.Encrypt(cfg)
2024-01-11 16:29:53 +00:00
2024-01-11 18:20:33 +00:00
promoCodeRepo := repository.NewPromoCodeRepository(mdb.Collection("promoCodes"))
2024-01-27 12:51:32 +00:00
statsRepo := repository.NewStatsRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("promoStats")})
2023-12-31 12:22:03 +00:00
codewordRepo := repository.NewCodewordRepository(repository.Deps{Rdb: rdb, Mdb: mdb.Collection("codeword")})
userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("users")})
2024-01-11 16:29:53 +00:00
2024-01-05 11:37:06 +00:00
recoveryEmailSender := initialize.RecoveryEmailSender(cfg, logger)
authClient := initialize.AuthClient(cfg, logger)
2023-12-29 18:02:50 +00:00
recoveryService := services.NewRecoveryService(services.Deps{
2023-12-31 12:22:03 +00:00
Logger: logger,
CodewordRepository: codewordRepo,
UserRepository: userRepo,
2024-01-04 11:27:50 +00:00
Encrypt: encrypt,
2024-01-04 14:57:30 +00:00
AuthClient: authClient,
2023-12-29 18:02:50 +00:00
})
2024-01-11 16:29:53 +00:00
promoService := services.NewPromoCodeService(services.PromoDeps{
2024-02-25 12:02:15 +00:00
Logger: logger,
PromoCodeRepo: promoCodeRepo,
StatsRepo: statsRepo,
Kafka: brokers.TariffProducer,
DiscountClient: discountRpcClient,
2024-01-11 16:29:53 +00:00
})
2024-01-11 18:20:33 +00:00
recoveryController := recovery.NewRecoveryController(logger, recoveryService, cfg.DefaultRedirectionURL)
promoCodeController := promocode.NewPromoCodeController(logger, promoService)
2023-12-29 12:41:26 +00:00
2024-01-03 13:50:11 +00:00
recoveryWC := recovery_worker.NewRecoveryWC(recovery_worker.Deps{
Logger: logger,
Redis: rdb,
EmailSender: recoveryEmailSender,
2024-01-03 15:45:41 +00:00
Mongo: mdb.Collection("codeword"),
2024-01-03 13:50:11 +00:00
})
2024-01-01 14:13:54 +00:00
2024-01-16 15:10:16 +00:00
purgeWC := purge_worker.NewPurgeWC(purge_worker.Deps{
2024-01-05 11:37:06 +00:00
Logger: logger,
Mongo: mdb.Collection("codeword"),
})
2024-01-01 14:13:54 +00:00
go recoveryWC.Start(ctx)
2024-01-05 11:37:06 +00:00
go purgeWC.Start(ctx)
2024-01-01 14:13:54 +00:00
2023-12-29 11:30:20 +00:00
server := httpserver.NewServer(httpserver.ServerConfig{
2024-02-25 12:00:05 +00:00
Logger: logger,
Controllers: []httpserver.Controller{recoveryController, promoCodeController},
2023-12-29 11:30:20 +00:00
})
go func() {
2023-12-29 12:41:26 +00:00
if err := server.Start(cfg.HTTPHost + ":" + cfg.HTTPPort); err != nil {
2024-01-05 11:37:06 +00:00
logger.Error("Server startup error", zap.Error(err))
2024-01-16 15:10:16 +00:00
cancel()
2023-12-29 11:30:20 +00:00
}
}()
2024-02-25 12:00:05 +00:00
server.ListRoutes()
2024-01-16 15:10:16 +00:00
shutdownGroup.Add(closer.CloserFunc(server.Shutdown))
shutdownGroup.Add(closer.CloserFunc(mdb.Client().Disconnect))
shutdownGroup.Add(closer.CloserFunc(recoveryWC.Stop))
shutdownGroup.Add(closer.CloserFunc(purgeWC.Stop))
2023-12-29 18:02:50 +00:00
2024-01-16 15:10:16 +00:00
<-ctx.Done()
2023-12-29 18:02:50 +00:00
2024-01-16 15:10:16 +00:00
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))
}
2023-12-29 18:02:50 +00:00
return err
}
2024-01-16 15:10:16 +00:00
logger.Info("Application has stopped")
2023-12-29 11:30:20 +00:00
return nil
}