package worker import ( "context" "sync" "time" "github.com/rs/zerolog/log" "github.com/TelegramExchange/tgex-backend/tg_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 }