86 lines
1.7 KiB
Go
86 lines
1.7 KiB
Go
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:"120s"`
|
|
}
|
|
|
|
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
|
|
}
|