fix(telegram): cancel delayed deliveries on disconnect - #55971
Merged
Conversation
Buffered text/photo/media-group flushes and the polling-error recovery task sit behind an asyncio.sleep(). On disconnect they kept running and dispatched handle_message() into a torn-down session, producing stale or duplicate deliveries. disconnect() only cancelled media-group and photo batch tasks — text batches and the polling-error task leaked. Set a _drop_delayed_deliveries flag from _mark_disconnected/_set_fatal_error (cleared by _mark_connected) and check it in all enqueue+flush paths so a flush that wins the race against teardown drops instead of dispatching. _cancel_pending_delivery_tasks() now cancels+clears all four task maps, skipping the current task. Media-group flush finally-block guarded so a cancelled stale flush cannot erase a replacement task handle.
teknium1
force-pushed
the
hermes/hermes-eee44b9d
branch
from
July 1, 2026 00:30
e868a78 to
b2a6f5f
Compare
16 tasks
dvbaecker
added a commit
to dvbaecker/hermes-agent
that referenced
this pull request
Aug 13, 2026
…troying them The disconnect drop-guard (NousResearch#55971) correctly prevents dispatch into a torn-down session. Destroying the event was wrong: by enqueue/flush time python-telegram-bot has already acked the update and advanced the polling offset, so Telegram never redelivers. Result: silent permanent loss, no log, no error. Hold inbound events (text/photo/media-group) when the drop-guard fires, salvage pending batch maps on teardown, cancel+await the redispatch task in the delivery cancel map (lifecycle-tracked), and redispatch from _mark_connected after reconnect. Cap the hold queue (default 64), dedupe by object identity, discard on non-retryable fatal. Cancel-after-pop in flush paths also holds. Distinct from NousResearch#72037 (cancel-after-pop during follow-up supersession) and NousResearch#81528 (boundary discard). Tests use delay=0 and entered/release Events — no wall-clock races; includes production terminal-step coverage.
kshitijk4poor
pushed a commit
that referenced
this pull request
Aug 15, 2026
…troying them The disconnect drop-guard (#55971) correctly prevents dispatch into a torn-down session. Destroying the event was wrong: by enqueue/flush time python-telegram-bot has already acked the update and advanced the polling offset, so Telegram never redelivers. Result: silent permanent loss, no log, no error. Hold inbound events (text/photo/media-group) when the drop-guard fires, salvage pending batch maps on teardown, cancel+await the redispatch task in the delivery cancel map (lifecycle-tracked), and redispatch from _mark_connected after reconnect. Cap the hold queue (default 64), dedupe by object identity, discard on non-retryable fatal. Cancel-after-pop in flush paths also holds. Distinct from #72037 (cancel-after-pop during follow-up supersession) and #81528 (boundary discard). Tests use delay=0 and entered/release Events — no wall-clock races; includes production terminal-step coverage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Telegram no longer dispatches buffered messages into a torn-down session after disconnect. Salvage of #17082 (@CRWuTJ), re-targeted onto current
mainwhere the adapter now lives atplugins/platforms/telegram/adapter.py.Root cause: text/photo/media-group flushes and the polling-error recovery task sit behind an
asyncio.sleep().disconnect()only cancelled the media-group and photo-batch tasks — the text-batch tasks and polling-error task leaked, and no flush had a drop guard, so any flush already past itssleep()still calledhandle_message()after teardown, spawning an agent on a dead session (stale / duplicate deliveries).Changes
plugins/platforms/telegram/adapter.py:_drop_delayed_deliveriesflag set by_mark_disconnected/_set_fatal_error, cleared by_mark_connected; checked in all 3 enqueue + 3 flush paths so a flush that loses the race to teardown drops instead of dispatching, and late update handlers don't schedule new delayed tasks during teardown._cancel_pending_delivery_tasks()cancels + clears all four task maps (media-group, photo, text, polling-error), skipping the current task; awaits only real awaitables.disconnect()calls_mark_disconnected()first, then the shared cancel helper (removes the two ad-hoc cancellation blocks).finallyblock guarded so a cancelled stale flush can't erase a replacement task handle.tests/gateway/test_telegram_text_batching.py: 9 regression tests (disconnect drops pending text/photo/media flushes, late enqueue dropped, stale media flush doesn't clear newer task, cancel helper skips current task, full disconnect clears all maps).scripts/release.py: AUTHOR_MAP entry for @CRWuTJ.Validation
-k telegram)test_telegram_text_batching.pyInfographic
Nous Research