Files
gomax/core/pollers.go
T

87 lines
1.6 KiB
Go

package core
import (
"context"
"errors"
"fmt"
maxbot "github.com/max-messenger/max-bot-api-client-go/v2"
"github.com/max-messenger/max-bot-api-client-go/v2/model"
"github.com/rs/zerolog/log"
"time"
)
const defaultInterval = 200 * time.Millisecond
type PollerOption interface{}
type Webhook struct{}
type LongPoller struct {
api *maxbot.Api
pollInterval time.Duration
}
type TestPoller struct{}
func (w *Webhook) Start(_ context.Context) (<-chan model.Update, error) {
return nil, fmt.Errorf("unimplemented")
}
func NewLongPoller(api *maxbot.Api, options ...PollerOption) *LongPoller {
lp := &LongPoller{
api: api,
}
if lp.pollInterval == 0 {
lp.pollInterval = defaultInterval
}
return lp
}
func (lp *LongPoller) Start(ctx context.Context) (<-chan model.Update, error) {
var updates []model.Update
var marker int64
var err error
ch := make(chan model.Update)
go func() {
defer close(ch)
// todo: backoff on errors
for {
select {
case <-ctx.Done():
return
case <-time.Tick(lp.pollInterval):
start := time.Now()
updates, marker, err = lp.api.Subscriptions.GetUpdates(ctx, marker)
latency := time.Since(start)
if err != nil && !errors.Is(err, context.Canceled) {
log.Error().Err(err).Send()
}
log.Ctx(ctx).Debug().
Int("received", len(updates)).
Dur("latency", latency).
Msg("received updates")
for _, update := range updates {
select {
case <-ctx.Done():
return
case ch <- update:
}
}
}
}
}()
return ch, nil
}
func (tp *TestPoller) Start(_ context.Context) (<-chan model.Update, error) {
return nil, fmt.Errorf("unimplemented")
}