package research import ( "context" "encoding/json" "gitea.pena/PenaDevops/smtpbiz-exporter/internal/client" "gitea.pena/PenaDevops/smtpbiz-exporter/internal/models" "go.uber.org/zap" "sync/atomic" "time" ) type Deps struct { Client *client.SMTPClient Logger *zap.Logger Frequency int64 } type Research struct { client *client.SMTPClient logger *zap.Logger frequency int64 Metrics Metrics } type Metrics struct { // Метрики отправленных писем и лимитов HourlyEmailsSent int64 // Количество писем, отправленных за последний час HourlyEmailLimit int64 // Лимит на количество писем, которые можно отправить за час DailyEmailsSent int64 // Количество писем, отправленных за текущий день DailyEmailLimit int64 // Лимит на количество писем, которые можно отправить за день // Метрики квот и баланса RemainingQuota int64 // Оставшееся количество писем, которые можно отправить в рамках текущего тарифа EmailValidationLimit int64 // Лимит на количество проверок наверное емейл адресов TariffQuota int64 // Общая квота на отправку писем, предоставляемая по тарифу Balance int64 // Баланс } func NewResearch(deps Deps) *Research { return &Research{ client: deps.Client, logger: deps.Logger, frequency: deps.Frequency, } } func (r *Research) Start(ctx context.Context) { ticker := time.NewTicker(time.Second * time.Duration(r.frequency)) defer ticker.Stop() for { select { case <-ticker.C: r.StartFetching(ctx) case <-ctx.Done(): return } } } func (r *Research) StartFetching(ctx context.Context) { data, err := r.client.UseGetMethod(models.UserDataEndpoint, nil) if err != nil { r.logger.Error("failed to fetch user data", zap.Error(err)) return } var userData models.UserDataResponse if err := json.Unmarshal(data, &userData); err != nil { r.logger.Error("failed to parse user data response", zap.Error(err)) return } atomic.StoreInt64(&r.Metrics.HourlyEmailsSent, userData.HSent) atomic.StoreInt64(&r.Metrics.HourlyEmailLimit, userData.HLimit) atomic.StoreInt64(&r.Metrics.DailyEmailsSent, userData.DSent) atomic.StoreInt64(&r.Metrics.DailyEmailLimit, userData.DLimit) atomic.StoreInt64(&r.Metrics.RemainingQuota, userData.Quota) atomic.StoreInt64(&r.Metrics.EmailValidationLimit, userData.Validate) atomic.StoreInt64(&r.Metrics.TariffQuota, userData.TariffQuota) atomic.StoreInt64(&r.Metrics.Balance, int64(userData.Balance)) }