diff options
Diffstat (limited to 'backend/internal/monitor')
| -rw-r--r-- | backend/internal/monitor/worker.go | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/backend/internal/monitor/worker.go b/backend/internal/monitor/worker.go index 0cf980a..70855a2 100644 --- a/backend/internal/monitor/worker.go +++ b/backend/internal/monitor/worker.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "log" + "sync" "time" "yaum/internal/alerts" @@ -25,6 +26,8 @@ type Worker struct { broadcaster *sse.Broadcaster smtpCfg *alerts.SMTPConfig quit chan struct{} + mu sync.Mutex + lastChecked map[int]time.Time } func NewWorker(s store.Store, interval, timeout time.Duration, b *sse.Broadcaster) *Worker { @@ -35,6 +38,7 @@ func NewWorker(s store.Store, interval, timeout time.Duration, b *sse.Broadcaste results: make(chan checkResult, 100), broadcaster: b, quit: make(chan struct{}), + lastChecked: make(map[int]time.Time), } } @@ -44,10 +48,14 @@ func (w *Worker) WithSMTP(cfg *alerts.SMTPConfig) *Worker { } func (w *Worker) Start(ctx context.Context) { - ticker := time.NewTicker(w.interval) + granularity := w.interval + if granularity > 10*time.Second { + granularity = 10 * time.Second + } + ticker := time.NewTicker(granularity) defer ticker.Stop() - log.Printf("[worker] iniciado | intervalo=%v timeout=%v", w.interval, w.timeout) + log.Printf("[worker] iniciado | global_interval=%v granularity=%v timeout=%v", w.interval, granularity, w.timeout) go w.resultConsumer() @@ -64,6 +72,40 @@ func (w *Worker) Start(ctx context.Context) { } } +func (w *Worker) runChecks(ctx context.Context) { + services, err := w.store.ListActiveServices() + if err != nil { + log.Printf("[worker] erro ao listar servicos ativos: %v", err) + return + } + + now := time.Now() + var due []model.Service + + w.mu.Lock() + for _, svc := range services { + svcInterval := time.Duration(svc.IntervalSeconds) * time.Second + if svcInterval <= 0 { + svcInterval = w.interval + } + last, ok := w.lastChecked[svc.ID] + if !ok || now.Sub(last) >= svcInterval { + w.lastChecked[svc.ID] = now + due = append(due, svc) + } + } + w.mu.Unlock() + + if len(due) == 0 { + return + } + log.Printf("[worker] verificando %d servico(s) de %d ativo(s)", len(due), len(services)) + + for _, svc := range due { + go w.checkService(ctx, svc) + } +} + func (w *Worker) resultConsumer() { for { select { @@ -120,19 +162,6 @@ func (w *Worker) fireAlerts(svc model.Service, hb model.Heartbeat, wasUp bool) { } } -func (w *Worker) runChecks(ctx context.Context) { - services, err := w.store.ListActiveServices() - if err != nil { - log.Printf("[worker] erro ao listar servicos ativos: %v", err) - return - } - log.Printf("[worker] verificando %d servico(s)", len(services)) - - for _, svc := range services { - go w.checkService(ctx, svc) - } -} - func (w *Worker) checkService(ctx context.Context, svc model.Service) { checkCtx, cancel := context.WithTimeout(ctx, w.timeout) defer cancel() |