init push
This commit is contained in:
99
cmd/worker/mail_worker.go
Normal file
99
cmd/worker/mail_worker.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
queueapp "wucher/internal/app/queueing"
|
||||
appworker "wucher/internal/app/worker"
|
||||
"wucher/internal/config"
|
||||
"wucher/internal/shared/pkg/logger"
|
||||
mysqlrepo "wucher/internal/repository/mysql"
|
||||
"wucher/internal/resilience"
|
||||
"wucher/internal/service"
|
||||
)
|
||||
|
||||
func runMailWorker(appCfg config.AppConfig) error {
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
appLogger := logger.New(appCfg.Logging).With("component", "worker", "job", "email")
|
||||
resCfg := appCfg.Resilience
|
||||
emailCfg := appCfg.Email
|
||||
|
||||
queueCfg := appCfg.Queue
|
||||
sqsCfg := appCfg.SQS
|
||||
db, err := mysqlrepo.Connect(appCfg.MySQL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authRepo := mysqlrepo.NewAuthRepository(db)
|
||||
|
||||
sqsBreaker := resilience.NewExecutor("sqs", resCfg.SQS, appLogger, resilience.ClassifySQSError)
|
||||
consumer, serializer, err := queueapp.NewEmailConsumer(ctx, queueCfg, sqsCfg, sqsBreaker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
idempotency := queueapp.NewIdempotencyStore(db, queueCfg)
|
||||
var dispatcher *appworker.OutboxDispatcher
|
||||
if queueCfg.OutboxEnabled {
|
||||
rawProducer, err := queueapp.NewQueueProducer(ctx, sqsCfg, sqsBreaker, "outbox_dispatcher")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dispatcher = appworker.NewOutboxDispatcher(queueCfg, authRepo, rawProducer, appLogger)
|
||||
}
|
||||
|
||||
emailSender, err := buildEmailSender(ctx, emailCfg, appCfg.SES, resCfg, appLogger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
handler := service.NewEmailDeliveryHandler(emailSender, appLogger)
|
||||
runner := appworker.NewRunner(queueCfg, consumer, serializer, handler, idempotency, dispatcher, appLogger)
|
||||
|
||||
appLogger.Info("worker started",
|
||||
"backend", "sqs",
|
||||
"email_provider", emailCfg.Provider,
|
||||
"monitor_addr", queueCfg.WorkerMonitorAddr,
|
||||
"outbox_enabled", queueCfg.OutboxEnabled,
|
||||
)
|
||||
if err := runner.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
appLogger.Info("worker stopped")
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildEmailSender(
|
||||
ctx context.Context,
|
||||
emailCfg config.EmailDeliveryConfig,
|
||||
sesCfg config.SESConfig,
|
||||
resCfg config.ResilienceConfig,
|
||||
appLogger *slog.Logger,
|
||||
) (service.EmailSender, error) {
|
||||
switch emailCfg.Provider {
|
||||
case "", "ses":
|
||||
sesBreaker := resilience.NewExecutor("ses", resCfg.SES, appLogger, resilience.ClassifySESError)
|
||||
sender, err := service.NewSESSender(ctx, sesCfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sender = sender.WithExecutor(sesBreaker)
|
||||
sender = sender.WithMetricsComponent("email_worker")
|
||||
if !sender.Configured() {
|
||||
return nil, errors.New("ses is not configured")
|
||||
}
|
||||
return sender, nil
|
||||
case "mock":
|
||||
sender := service.NewMockEmailSender(emailCfg.MockDir)
|
||||
if !sender.Configured() {
|
||||
return nil, errors.New("mock email sender is not configured")
|
||||
}
|
||||
return sender, nil
|
||||
default:
|
||||
return nil, errors.New("unsupported email provider: " + emailCfg.Provider)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user