Files
tgex-backend/tg_parser/internal/controller/worker/channel_worker.go
Artem Tsyrulnikov 2c0ae2dfc3 парсер
2026-01-06 21:06:21 +03:00

86 lines
1.7 KiB
Go

package worker
import (
"context"
"sync"
"time"
"github.com/rs/zerolog/log"
"github.com/TelegramExchange/tgex-parser/internal/usecase"
)
type ChannelConfig struct {
MaxWorkers int `envconfig:"WORKER__MAX_WORKERS" default:"1"`
ChannelDelay time.Duration `envconfig:"WORKER__CHANNEL_DELAY" default:"500ms"`
RequestTimeout time.Duration `envconfig:"WORKER__REQUEST_TIMEOUT" default:"10s"`
MessagesLimit int `envconfig:"WORKER__MESSAGES_LIMIT" default:"20"`
PollInterval time.Duration `envconfig:"WORKER__POLL_INTERVAL" default:"20s"`
}
type ChannelWorker struct {
usecase *usecase.UseCase
config ChannelConfig
stop chan struct{}
done chan struct{}
}
func NewChannelWorker(uc *usecase.UseCase, cfg ChannelConfig) *ChannelWorker {
w := &ChannelWorker{
usecase: uc,
config: cfg,
stop: make(chan struct{}),
done: make(chan struct{}),
}
go w.run()
return w
}
func (w *ChannelWorker) run() {
log.Info().Msg("channel worker: started")
var wg sync.WaitGroup
wg.Add(w.config.MaxWorkers)
for range w.config.MaxWorkers {
go w.spawnWorker(&wg)
}
wg.Wait()
log.Info().Msg("channel worker: stopped")
close(w.done)
}
func (w *ChannelWorker) spawnWorker(wg *sync.WaitGroup) {
defer wg.Done()
limiter := time.NewTicker(w.config.ChannelDelay)
defer limiter.Stop()
poll := time.NewTicker(w.config.PollInterval)
defer poll.Stop()
for {
select {
case <-w.stop:
return
case <-poll.C:
err := w.usecase.FetchChannels(context.Background())
if err != nil {
log.Error().Err(err).Msg("usecase.FetchChannels error")
}
}
}
}
func (w *ChannelWorker) Stop() {
close(w.stop)
<-w.done
}