Skip to content

fix(telegram): release fallback transport pools on connect failure (salvage of #71593 by @aneym) - #72359

Merged
teknium1 merged 2 commits into
mainfrom
salvage/71593-telegram-fallback-pool-release
Jul 27, 2026
Merged

teknium1 merged 2 commits into
mainfrom
salvage/71593-telegram-fallback-pool-release

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Summary

The Telegram fallback transport no longer leaks a file descriptor per failed connect, which previously accumulated CLOSE_WAIT sockets until EMFILE wedged the entire gateway.

Root cause: TelegramFallbackTransport built per-IP httpx pools eagerly and, on a retryable connect failure, only logged and continued — retaining the poisoned pool. The author observed 177 CLOSE_WAIT sockets against launchd's 256 soft limit.

Changes

  • plugins/platforms/telegram/telegram_network.py: build fallback pools lazily; on retryable failure _reset_fallback pops + aclose()s the pool; Limits(max_connections=8) added as a default via setdefault (caller-supplied limits still win); lock-safe aclose().
  • Regression tests (the PR body claimed a test but the diff shipped none — added on top): failed pool discarded+closed, working pool retained, caller limits win over default, default applied when omitted. Sabotage-checked (reverting _reset_fallback fails the test).

Validation

5 tests passed; production-verified 0 CLOSE_WAIT after fix.

Salvage of #71593@aneym's commit cherry-picked with authorship preserved; regression test added as a maintainer follow-up.

Infographic

Telegram fallback pool release

aneym and others added 2 commits July 26, 2026 18:08
The per-IP httpx transports were built once in __init__ and never torn
down. A connect that reached ESTABLISHED and was then closed by the peer
left its socket in CLOSE_WAIT inside the pool, and the failure path only
logged and continued — so the poisoned pool was retained and leaked one
descriptor per retry.

With DNS for api.telegram.org failing, every poll fell through to the
seed IP and leaked another fd every ~2.5s. The bot gateway reached 177
CLOSE_WAIT sockets against launchd's 256 soft limit and wedged: accept()
on the gateway port, config reads and DNS resolution all failed with
EMFILE, which in turn made the primary path fail and fed the loop.

Build fallback transports lazily and discard them on a retryable connect
failure, and bound every pool at 8 connections (httpx defaults to 100,
so two seed IPs plus primary could alone exceed the fd ceiling).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
The salvaged fix (#71593) rebuilds Telegram fallback pools lazily and
discards+aclose()s a pool on retryable connect failure (_reset_fallback),
bounding each at Limits(max_connections=8) as a setdefault default. The PR
shipped no test.

Add tests/gateway/test_telegram_fallback_pool_release_71593.py:
  * failed fallback pool is aclose()d and dropped from _fallbacks (the
    discard-on-failure path — reverting the _reset_fallback call fails it)
  * a recovered pool is retained, only the failed one discarded
  * _reset_fallback is a no-op when the pool was never built
  * caller-supplied limits win over the _POOL_LIMITS setdefault default
  * the max_connections=8 default applies when the caller omits limits

Update the eager-build assumptions in test_telegram_network.py to the new
lazy contract (fallbacks materialize via _get_fallback, not in __init__).
@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins platform/telegram Telegram bot adapter P3 Low — cosmetic, nice to have sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Jul 27, 2026
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 925a304

all good!

@teknium1
teknium1 merged commit 71c9910 into main Jul 27, 2026
41 checks passed
@teknium1
teknium1 deleted the salvage/71593-telegram-fallback-pool-release branch July 27, 2026 02:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have platform/telegram Telegram bot adapter sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants