Repository navigation
fix(runtime): replay failed reconnect result to queued callers - #310
Merged
Merged
Conversation
chigwell#292 serialized reconnects but only reused a successful one: when _force_reconnect failed, every queued caller ran its own full disconnect+connect (up to 30s each) and hit the 55s tool timeout with an opaque GEN-TIMEOUT instead of the real reconnect error. Cache the outcome of the last reconnect per client and replay it to waiters while it is fresh (_RECONNECT_FAILURE_TTL); a successful reconnect clears the cache so the next verification cycle runs normally. Fixes chigwell#298 Co-Authored-By: Claude Code <[email protected]>
chigwell
approved these changes
Oct 17, 2026
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
Follow-up to #292 (issue #298): reconnects are serialized per client, but only a successful reconnect result was reused. When
_force_reconnectfailed, every queued caller ran its own full disconnect+connect and hit the 55 s tool timeout with an opaqueGEN-TIMEOUTinstead of the real reconnect error.Cache the reconnect outcome per client under the same lock key and replay it to waiters while it is fresh (
_RECONNECT_FAILURE_TTL = 30 s); a successful reconnect clears the cache so the next verification cycle runs normally.Before
The connection drops while 3 tool calls share one client (streamable HTTP). Only the first caller actually reconnects; each queued caller ran its own full disconnect+connect (up to 30 s each, serially):
The last callers got an opaque timeout instead of the actual reconnect error.
After
The first failed reconnect is cached under the connection lock and replayed to every queued caller while it is fresh:
If the network recovers, a successful reconnect clears the cache and the normal verify-ping cycle resumes; a stale failure (older than 30 s) triggers a fresh reconnect attempt.
Changes
telegram_mcp/runtime.py:_reconnect_oncewraps both_force_reconnectcall sites inensure_connectedand records(timestamp, error)on failure / clears on success;_raise_cached_reconnect_failurereplays a fresh failure on thenot is_connected()path instead of repeating the attempt.tests/test_runtime.py: autouse fixture resets the reconnect state dicts (they are keyed byid(client), which CPython reuses across tests); new tests: 3 concurrent callers with a failingconnect()produce exactly one connect/disconnect attempt and all get the originalConnectionError; a stale cached failure is retried and cleared on success.Tests
uv run pytest -q— 1194 passed (full suite, includes the 2 new tests).Fixes #298
🤖 Generated with Claude Code