fix: changed dispatcher lifecycle interfaces

This commit is contained in:
abelith committed 2026-10-08 16:30:03 +03:00
1 parent cb1ed91e05
commit 5f03d4d832
2 files changed
+57 -32

No files matched your search

+5
View File
@@ -39,6 +39,7 @@ type UpdateHandler interface {
type Poller interface { type Poller interface {
Start(ctx context.Context) (<-chan model.Update, error) Start(ctx context.Context) (<-chan model.Update, error)
Stop(ctx context.Context) error
} }
type DispatcherOption interface { type DispatcherOption interface {
@@ -109,6 +110,10 @@ func (d *Dispatcher) Start(ctx context.Context) error {
return nil return nil
} }
func (d *Dispatcher) Stop(ctx context.Context) error {
return d.poller.Stop(ctx)
}
func (d *Dispatcher) handleUpdates(ch <-chan model.Update) { func (d *Dispatcher) handleUpdates(ch <-chan model.Update) {
for upd := range ch { for upd := range ch {
d.wg.Go(func() { d.wg.Go(func() {
+52 -32
View File
@@ -34,6 +34,7 @@ type Webhook struct {
type LongPoller struct { type LongPoller struct {
api *maxbot.Api api *maxbot.Api
pollInterval time.Duration pollInterval time.Duration
wg sync.WaitGroup
} }
type TestPoller struct { type TestPoller struct {
@@ -148,45 +149,32 @@ func NewLongPoller(api *maxbot.Api, options ...LongPollerOption) *LongPoller {
} }
func (lp *LongPoller) Start(ctx context.Context) (<-chan model.Update, error) { 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) ch := make(chan model.Update)
go func() { lp.wg.Go(func() {
defer close(ch) defer close(ch)
lp.poll(ctx, 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 ch <- update:
}
}
}
}
}()
return ch, nil return ch, nil
} }
func (lp *LongPoller) Stop(ctx context.Context) error {
done := make(chan struct{})
go func() {
lp.wg.Wait()
done <- struct{}{}
}()
select {
case <-ctx.Done():
return ctx.Err()
case <-done:
return nil
}
}
func (tp *TestPoller) Inject(ctx context.Context, updates []model.Update) { func (tp *TestPoller) Inject(ctx context.Context, updates []model.Update) {
ch := make(chan model.Update, 1) ch := make(chan model.Update, 1)
@@ -264,6 +252,38 @@ func WithConnContext(fn func(ctx context.Context, c net.Conn) context.Context) W
}) })
} }
func (lp *LongPoller) poll(ctx context.Context, ch chan model.Update) {
var updates []model.Update
var marker int64
var err error
// 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 ch <- update:
}
}
}
}
}
func newLongPollerOptions() *longPollerOptions { func newLongPollerOptions() *longPollerOptions {
return &longPollerOptions{ return &longPollerOptions{
pollInterval: defaultInterval, pollInterval: defaultInterval,