Skip to content

Retry other resolved addresses when a source host is partially blocked#30

Open
Zmeikich wants to merge 3 commits into
kimght:mainfrom
Zmeikich:connection-ip-fallback
Open

Retry other resolved addresses when a source host is partially blocked#30
Zmeikich wants to merge 3 commits into
kimght:mainfrom
Zmeikich:connection-ip-fallback

Conversation

@Zmeikich

@Zmeikich Zmeikich commented Jul 19, 2026

Copy link
Copy Markdown

Problem

Some ISPs (notably in Russia) block individual IP addresses of *.githubusercontent.com.
gist.githubusercontent.com resolves to four addresses (185.199.108.133 – 185.199.111.133),
and when only some of them are blocked, the Github source fails intermittently:

Failed to fetch available localizations: Request error
Caused by:
0: error sending request for url (https://gist.githubusercontent.com/kimght/322a2779922ab5a5f96ff7f7dc3f8e82/raw/localizations.json)
1: client error (Connect)
2: os error 10054 (connection reset by peer)

Whether a request succeeds depends purely on which address the OS resolver happens to
return, so the app appears "randomly broken" for affected users. The same issue affects
localization downloads and fonts (release-assets.githubusercontent.com,
raw.githubusercontent.com share the same address pool).

Fix

  • When a request fails to connect (or times out), the failing host is re-resolved and the
    request is retried with each address pinned in turn (5 s connect timeout per address)
    until one works. The failing host is taken from the reqwest error, so redirect targets
    (e.g. github.comrelease-assets.githubusercontent.com) are handled too.
  • The shared client got a 10 s connect timeout so a blocked address can't eat the whole
    30 s request timeout.
  • While addresses are being cycled, the backend emits a connection_status event and the
    localizations loading screen shows what is happening instead of a bare spinner
    ("Can't connect directly, trying 185.199.111.133:443"). Messages are translated for all
    supported languages.
  • The first working address found for a host is saved to address_cache.json in the
    app config directory and used for subsequent requests and launches, so users on
    affected networks only wait through the discovery once. If a saved address stops
    working, it is dropped and rediscovered automatically.

Testing

Tested on a real network where the ISP blocks 185.199.110.133:

WARN Request to https://gist.githubusercontent.com/... failed to connect, retrying each address of gist.githubusercontent.com
WARN Address 185.199.110.133:443 of gist.githubusercontent.com failed
INFO Connected to gist.githubusercontent.com via 185.199.111.133:443

Previously the Github source failed whenever the resolver picked the blocked address;
now the list, downloads and fonts recover ~5 s after the first failed attempt, with the
status line visible during the retry. Also verified that behavior on unaffected networks is unchanged
(cargo check and pnpm build pass, no new warnings).
Restarting the app after discovery connects through the saved address immediately
(Loaded saved addresses in the log, no retry delay).

Zmeikich and others added 3 commits July 19, 2026 16:35
Some ISPs block individual CDN addresses, so requests to a source (e.g.
gist.githubusercontent.com) fail or succeed depending on which of its
addresses the system resolver happens to return. When a request fails to
connect or times out, resolve the failing host (which may differ from
the original url's host after a redirect) and retry with each address
pinned in turn until one works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When the direct connection fails and addresses are being cycled, emit a
connection_status event from the backend and show what is happening on
the localizations loading screen instead of a bare spinner. Messages are
translated for all supported languages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When the fallback finds a working address, save it to address_cache.json
in the app config directory and route requests to that host through it
from the start, so later launches connect immediately instead of waiting
out the failing direct attempt. If a saved address stops working it is
dropped and rediscovered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant