fix(telegram): keep update retry checks read-only (#115613)

Use the non-mutating dedupe-cache contract when checking unaccepted Telegram updates. Preserve active handler and completed-update deduplication while allowing a real update to be accepted after repeated handler skip probes.

Fixes #105192
This commit is contained in:
Peter Steinberger
2026-07-29 04:02:55 -04:00
committed by GitHub
parent 263d1763d7
commit c650d2c8c9
2 changed files with 20 additions and 1 deletions

View File

@@ -437,6 +437,25 @@ describe("createTelegramUpdateTracker", () => {
});
});
it("does not record an update when checking handler dispatch before acceptance", () => {
const onSkip = vi.fn();
const tracker = createTelegramUpdateTracker({ initialUpdateId: 300, onSkip });
const ctx = updateCtx(301);
expect(tracker.shouldSkipHandlerDispatch(ctx)).toBe(false);
expect(tracker.shouldSkipHandlerDispatch(ctx)).toBe(false);
expect(onSkip).not.toHaveBeenCalled();
const accepted = tracker.beginUpdate(ctx);
if (!accepted.accepted) {
throw new Error("expected read-only skip checks to leave the update retryable");
}
expect(tracker.shouldSkipHandlerDispatch(ctx)).toBe(false);
tracker.finishUpdate(accepted.update, { completed: true });
expect(tracker.shouldSkipHandlerDispatch(ctx)).toBe(true);
});
it("dedupes handler dispatch separately from the accepted watermark", () => {
const onSkip = vi.fn();
const tracker = createTelegramUpdateTracker({ initialUpdateId: 300, onSkip });

View File

@@ -306,7 +306,7 @@ export function createTelegramUpdateTracker(options: TelegramUpdateTrackerOption
activeHandledUpdateKeys.set(key, true);
return false;
}
const skipped = recentUpdates.check(key);
const skipped = recentUpdates.peek(key);
if (skipped) {
skip(key);
}