(new): updates iterator
Golang lint / lint (push) Successful in 2m15s

(new): sneklog migration

(refactor): idiomatic names

(fix): polling lifecycle

(tests): polling regressions

(doc): rc16 changelog
This commit is contained in:
2026-04-29 12:31:41 +03:00
parent fc4386df75
commit 667fa3cc61
5 changed files with 174 additions and 8 deletions
+52 -2
View File
@@ -24,12 +24,13 @@ func (f pollingRoundTripFunc) RoundTrip(req *http.Request) (*http.Response, erro
type pollingRetryObserver struct {
recordingObserver
cancel context.CancelFunc
cancel context.CancelFunc
cancelAfter int
}
func (o *pollingRetryObserver) OnPollingRetry(ctx context.Context, ev PollingRetryEvent) {
o.recordingObserver.OnPollingRetry(ctx, ev)
if o.cancel != nil {
if o.cancel != nil && (o.cancelAfter == 0 || len(o.retries) >= o.cancelAfter) {
o.cancel()
}
}
@@ -510,6 +511,55 @@ func TestRunWithContextEmitsPollingRetryAndErrorEvents(t *testing.T) {
}
}
func TestRunWithContextPreservesPollingRetryBackoff(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
observer := &pollingRetryObserver{cancel: cancel, cancelAfter: 2}
client := &http.Client{
Transport: pollingRoundTripFunc(func(r *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Header: http.Header{"Content-Type": []string{"application/json"}},
Body: io.NopCloser(strings.NewReader(`{"ok":false,"error_code":500,"description":"boom"}`)),
}, nil
}),
}
api := tgapi.NewAPI(
tgapi.NewAPIOpts("token").
SetAPIURL("http://example.invalid").
SetHTTPClient(client),
)
defer func() {
_ = api.Close()
}()
bot := &Bot[NoData]{
logger: sneklog.NewLogger(),
api: api,
prefixes: []string{"/"},
plugins: []Plugin[NoData]{{name: "demo"}},
updateQueue: make(chan *tgapi.Update, 1),
maxWorkers: 1,
observer: observer,
}
if err := bot.RunWithContext(ctx); err != nil {
t.Fatalf("RunWithContext returned error: %v", err)
}
if len(observer.retries) != 2 {
t.Fatalf("expected two polling retry events, got %d", len(observer.retries))
}
if got := observer.retries[0]; got.Attempt != 1 || got.Delay != time.Second {
t.Fatalf("unexpected first retry event: %#v", got)
}
if got := observer.retries[1]; got.Attempt != 2 || got.Delay != 2*time.Second {
t.Fatalf("unexpected second retry event: %#v", got)
}
}
func TestBotConfigurationFreezesAfterRunStarts(t *testing.T) {
type testDB struct{ Name string }