Skip to content

Fix DownloadManager hanging on stalled connections#98

Merged
ThomasFarstrike merged 1 commit into
MicroPythonOS:mainfrom
bitcoin3us:fix/download-manager-connection-timeout
Mar 30, 2026
Merged

Fix DownloadManager hanging on stalled connections#98
ThomasFarstrike merged 1 commit into
MicroPythonOS:mainfrom
bitcoin3us:fix/download-manager-connection-timeout

Conversation

@bitcoin3us
Copy link
Copy Markdown
Contributor

Summary

  • Added connection timeout to session.get() in DownloadManager._download_url_async()
  • Previously only individual chunk reads had a timeout (_CHUNK_TIMEOUT_SECONDS), but the initial TCP/TLS connection had none
  • On ESP32 devices with intermittent WiFi, a stalled connection would hang the entire async balance fetch loop forever, freezing the wallet UI

Root cause

session.get(url, headers=headers) at line 118 of download_manager.py had no timeout parameter. If the TLS handshake or TCP connection stalled, this await would never return, blocking the calling coroutine permanently.

Fix

Pass the existing _CHUNK_TIMEOUT_SECONDS (10s) as the timeout for session.get(), so stalled connections fail gracefully and the caller's retry logic can recover.

Test plan

  • Verify normal downloads still work (balance fetch, payments fetch)
  • Verify that a stalled connection times out after 10s instead of hanging
  • Verify the wallet recovers on the next fetch cycle after a timeout

🤖 Generated with Claude Code

The HTTP connection (session.get) had no timeout, only individual chunk
reads did. If the TCP connection or TLS handshake stalled, the entire
async balance fetch loop would hang forever. This was observed on ESP32
devices where intermittent WiFi issues caused session.get() to never
return, freezing the wallet UI on "Connecting to backend".

Uses the existing _CHUNK_TIMEOUT_SECONDS (10s) for the connection timeout.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@bitcoin3us bitcoin3us force-pushed the fix/download-manager-connection-timeout branch from 6ca8783 to 81a907c Compare March 30, 2026 07:43
@ThomasFarstrike
Copy link
Copy Markdown
Contributor

Splendit!

@ThomasFarstrike ThomasFarstrike merged commit 787cec8 into MicroPythonOS:main Mar 30, 2026
4 checks passed
@bitcoin3us bitcoin3us deleted the fix/download-manager-connection-timeout branch March 30, 2026 13:54
bitcoin3us pushed a commit to bitcoin3us/MicroPythonOS that referenced this pull request Mar 31, 2026
The desktop aiohttp implementation doesn't support the timeout
keyword argument added in MicroPythonOS#98. Fall back to calling session.get()
without timeout when TypeError is raised, so downloads work on
both ESP32 (with timeout) and desktop (without).

Fixes test_custom_headers and test_json_download failures on
desktop builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
bitcoin3us pushed a commit to bitcoin3us/MicroPythonOS that referenced this pull request Mar 31, 2026
The MicroPython aiohttp library had no timeout support (marked as TODO).
Add a timeout parameter to request_raw(), _request(), and request()
that wraps asyncio.open_connection() with asyncio.wait_for().

This allows DownloadManager to use session.get(timeout=...) to prevent
connections from hanging indefinitely on stalled TCP/TLS handshakes,
which was the original fix in MicroPythonOS#98.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
ThomasFarstrike pushed a commit that referenced this pull request Mar 31, 2026
…107)

* Fix DownloadManager timeout kwarg compatibility with desktop aiohttp

The desktop aiohttp implementation doesn't support the timeout
keyword argument added in #98. Fall back to calling session.get()
without timeout when TypeError is raised, so downloads work on
both ESP32 (with timeout) and desktop (without).

Fixes test_custom_headers and test_json_download failures on
desktop builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Add connection timeout support to aiohttp and restore in DownloadManager

The MicroPython aiohttp library had no timeout support (marked as TODO).
Add a timeout parameter to request_raw(), _request(), and request()
that wraps asyncio.open_connection() with asyncio.wait_for().

This allows DownloadManager to use session.get(timeout=...) to prevent
connections from hanging indefinitely on stalled TCP/TLS handshakes,
which was the original fix in #98.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Richard Taylor <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants