87 lines
1.6 KiB
Go
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")
|
|
}
|