Conversation
…b cannot hang the UI The three GitHub requests (latest release, announce commit, announce content) were sent without a timeout. On a network where GitHub is unreachable but not refused — dropped packets, captive portal, a proxy that accepts and stalls — the request stayed pending forever, and with it the future the controller was waiting on: the frontend sat on its "fetching" toast for the whole session. Every request now carries HTTP_TIMEOUT_MS (5 s). On timeout the future fails, which the controller already turns into a 500 and the frontend into a logged error or an error toast. The built-in announce is deliberately not used as a fallback: popping the 2020 announce on every offline start would be a regression of its own. A package-private constructor makes host, port, TLS and timeout injectable. EvergreenServiceTimeoutTest aims the service at a local server that never answers and asserts each future fails within a bound with a TimeoutException, for each of the three requests (the second hop of announce() included), plus the nominal two-hop path as a control. Without the timeouts the three stalling cases hang until the test bound. Closes #11 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 tasks
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.
What
EvergreenServicesent its three GitHub requests (latest release, announce commit, announce content) without any timeout. On a network where GitHub is unreachable but not refused — dropped packets, captive portal, a proxy that accepts and stalls — the request stayed pending forever, and with it the future the controller was waiting on. The frontend then sat on its "fetching" toast for the whole session.Every request now carries
HTTP_TIMEOUT_MS(5 s). On timeout the future fails;EvergreenControlleralready turns that into a 500, andactionLoadEvergreenalready turns that into a logged error (announce) or an error toast (latest release). Failing fast is the whole fix.Not done on purpose: falling back to the built-in announce on timeout. That text is the 2020 first-announce, only meant for the "no commits on ANNOUNCE.md yet" case; showing it whenever GitHub is unreachable would pop an obsolete modal on every offline start.
Seam
A package-private constructor makes the API host, raw host, port, TLS and timeout injectable. Production keeps the single public constructor; nothing else changes.
Tests
EvergreenServiceTimeoutTest(5 tests) starts a local Vert.x server that deliberately never answers on a chosen path and asserts that each future completes — failed, with aTimeoutExceptionas the cause — within a bound, for:latest()announce()when the commit lookup stallsannounce()when only the content fetch stalls (the second hop must be bounded too)plus the nominal
latest()and two-hopannounce()against the same server answering, as controls. Verified red without the.timeout(...)calls: the three stalling cases hang until the test bound (3 failures).Locally:
mvn -B -Dskip.installnodeyarn=true -Dskip.yarn=true test→ 327 run, 0 failures, 0 errors, 39 skipped (FAT32 opt-in).git diff --exit-codeclean. Frontend untouched.Tracked in lgnap#11.
🤖 Generated with Claude Code