worker/app/app.go
2024-09-21 01:32:08 +03:00

217 lines
6.5 KiB
Go

package app
import (
"context"
"errors"
"fmt"
"github.com/go-redis/redis/v8"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/skeris/appInit"
"github.com/themakers/hlog"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/clients"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
"penahub.gitlab.yandexcloud.net/backend/quiz/worker/answerwc"
"penahub.gitlab.yandexcloud.net/backend/quiz/worker/privilegewc"
"penahub.gitlab.yandexcloud.net/backend/quiz/worker/senders"
"penahub.gitlab.yandexcloud.net/backend/quiz/worker/workers/shortstat"
"penahub.gitlab.yandexcloud.net/backend/quiz/worker/workers/timeout"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/customer_clients"
"time"
)
type App struct {
logger *zap.Logger
err chan error
}
func (a App) GetLogger() *zap.Logger {
return a.logger
}
func (a App) GetErr() chan error {
return a.err
}
var (
errInvalidOptions = errors.New("invalid options")
)
var zapOptions = []zap.Option{
zap.AddCaller(),
zap.AddCallerSkip(2),
zap.AddStacktrace(zap.ErrorLevel),
}
var _ appInit.CommonApp = (*App)(nil)
type Options struct {
ServiceName string `env:"SERVICE_NAME" default:"squiz"`
KafkaBroker string `env:"KAFKA_BROKER" default:"localhost:6379"`
KafkaTopic string `env:"KAFKA_TOPIC" default:"test-topic"`
LoggerProdMode bool `env:"IS_PROD_LOG" default:"false"`
IsProd bool `env:"IS_PROD" default:"false"`
MinioEP string `env:"MINIO_EP" default:"localhost:3002"`
MinioAK string `env:"MINIO_AK" default:"minio"`
MinioSK string `env:"MINIO_SK" default:"miniostorage"`
PostgresCredentials string `env:"PG_CRED" default:"host=localhost port=35432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"`
RedisHost string `env:"REDIS_HOST" default:"localhost:6379"`
RedisPassword string `env:"REDIS_PASSWORD" default:"admin"`
RedisDB uint64 `env:"REDIS_DB" default:"2"`
SmtpHost string `env:"SMTP_HOST" default:"connect.mailclient.bz"`
SmtpPort string `env:"SMTP_PORT" default:"587"`
SmtpSender string `env:"SMTP_SENDER" default:"noreply@mailing.pena.digital"`
SmtpUsername string `env:"SMTP_USERNAME" default:"kotilion.95@gmail.com"`
SmtpPassword string `env:"SMTP_PASSWORD" default:"vWwbCSg4bf0p"`
SmtpApiKey string `env:"SMTP_API_KEY" default:"P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev"`
SmtpApiUrl string `env:"SMTP_API_URL" default:"https://api.smtp.bz/v1/smtp/send"`
CustomerServiceAddress string `env:"CUSTOMER_SERVICE_ADDRESS" default:"localhost:9001"`
TgToken string `env:"TG_TOKEN"`
}
func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) {
var (
err, workerErr error
zapLogger *zap.Logger
errChan = make(chan error)
options Options
ok bool
)
if options, ok = opts.(Options); !ok {
return App{}, errInvalidOptions
}
if options.LoggerProdMode {
zapLogger, err = zap.NewProduction(zapOptions...)
if err != nil {
return nil, err
}
} else {
zapLogger, err = zap.NewDevelopment(zapOptions...)
if err != nil {
return nil, err
}
}
zapLogger = zapLogger.With(
zap.String("SvcCommit", ver.Commit),
zap.String("SvcVersion", ver.Release),
zap.String("SvcBuildTime", ver.BuildTime),
)
logger := hlog.New(zapLogger)
logger.Emit(InfoSvcStarted{})
zapLogger.Info("config", zap.Any("options", options))
go func() {
for {
select {
case <-ctx.Done():
return
case err := <-errChan:
zapLogger.Error("Ошибка при работе воркера", zap.Error(err))
}
}
}()
//init redis
redisClient := redis.NewClient(&redis.Options{
Addr: options.RedisHost,
Password: options.RedisPassword,
DB: int(options.RedisDB),
})
mailClent := clients.NewSmtpClient(clients.Deps{
SmtpHost: options.SmtpHost,
SmtpPort: options.SmtpPort,
SmtpSender: options.SmtpSender,
ApiKey: options.SmtpApiKey,
SmtpApiUrl: options.SmtpApiUrl,
})
// tgSender, err := senders.NewTgSender(options.TgToken)
// if err != nil {
// fmt.Println(err)
// return nil, err
// }
mailSender := senders.NewMailLeadSender(mailClent)
leadSenders := []senders.LeadSender{mailSender/* , tgSender */}
customerClient := customer_clients.NewCustomersClient(customer_clients.CustomersClientDeps{
Logger: zapLogger,
CustomerServiceHost: options.CustomerServiceAddress,
})
minioClient, err := minio.New(options.MinioEP, &minio.Options{
Creds: credentials.NewStaticV4(options.MinioAK, options.MinioSK, ""),
Secure: options.IsProd,
})
if err != nil {
fmt.Println("MINIOERR", options.MinioEP, err)
return nil, err
}
pgdal, err := dal.New(ctx, options.PostgresCredentials, minioClient)
if err != nil {
return nil, err
}
kafkaWorker, err := privilegewc.NewKafkaConsumerWorker(privilegewc.Config{
KafkaBroker: options.KafkaBroker,
KafkaTopic: options.KafkaTopic,
ServiceKey: options.ServiceName,
TickerInterval: time.Second * 10,
ErrChan: errChan,
}, redisClient, pgdal)
if err != nil {
logger.Module("Failed start privilege worker")
return nil, err
}
checkWorker := privilegewc.NewCheckWorker(privilegewc.Deps{
PrivilegeIDsDays: []string{"quizUnlimTime", "squizHideBadge"},
PrivilegeIDsCount: []string{"quizCnt", "quizManual"},
TickerInterval: time.Minute,
PrivilegeDAL: pgdal,
CustomerClient: customerClient,
}, errChan)
go kafkaWorker.Start(ctx)
go checkWorker.Start(ctx)
toClientWorker := answerwc.NewSendToClient(answerwc.DepsSendToClient{
Redis: redisClient,
Dal: pgdal,
LeadSenders: leadSenders,
CustomerService: customerClient,
}, errChan)
toRespWorker := answerwc.NewRespWorker(answerwc.DepsRespWorker{
Redis: redisClient,
Dal: pgdal,
MailClient: mailSender,
}, errChan)
go toClientWorker.Start(ctx)
go toRespWorker.Start(ctx)
tow := timeout.New(pgdal, time.Minute)
statW := shortstat.New(pgdal, 5*time.Minute)
tow.ExposeErr(ctx, &workerErr)
statW.ExposeErr(ctx, &workerErr)
go tow.Start(ctx)
go func() {
// defer pgdal.CloseWorker()
statW.Start(ctx)
}()
logger.Emit(InfoSvcReady{})
// todo implement helper func for service app type. such as server preparing, logger preparing, healthchecks and etc.
return &App{
logger: zapLogger,
err: make(chan error),
}, err
}