Skip to content

Connection groups: a member answering LOADING triggers an immediate re-probe and re-select - #3289

Merged
mgravell merged 1 commit into
mainfrom
marc/group-loading-failover
Oct 22, 2026
Merged

mgravell merged 1 commit into
mainfrom
marc/group-loading-failover

Conversation

@mgravell

Copy link
Copy Markdown
Collaborator

The group's ConnectionFailed fast-path only reacted to ConnectionFailureType.CircuitBreaker. A server that is loading its dataset fails every reconnect during the handshake, so commands routed to it die in the backlog without a reply, and the circuit breaker only observes replies (PhysicalConnection.ObserveMessageResult): it can never be what moves traffic away from a loading member.

This is the shape of the most persistent Windows CI flake, RetryEndToEndTests.WithRetry_FailsOverBetweenGroupsOnLoading (six failed attempts in twelve days, net481 only, always 1m41s = 20 attempts x 5000ms backlog timeout). When the heartbeat rather than the test's GET met the first -LOADING, member A's connection was torn down, its handshake ECHO kept getting LOADING, every attempt queued against A and timed out, and the group never failed over.

Change: Loading joins CircuitBreaker in the fast-path: mark the member unhealthy, re-probe, re-select, debounced as before. The health check still decides where traffic goes, so a member whose probe passes is kept (WithRetry_WhenFailoverNeverArrives_KeepsRetryingSameMember is unchanged and still passes). Ordinary socket drops are still left to reconnect.

Verification

  • New LoadingRerouteTests.LoadingMember_ReroutesAwayPromptly fails without the library change (both protocols) and passes with it.
  • Group, retry and availability suites (241 tests) pass; 10 two-core runs of the reroute and retry end-to-end tests clean.
  • docs/Failover.md updated. Release build of Build.csproj clean.

Companion test-only stabilisation: see the marc/ci-flakes PR.

…e-probe and re-select, like a breaker trip

The group's fast-path only reacted to ConnectionFailureType.CircuitBreaker. A server that is loading fails every
reconnect during the handshake, so commands routed to it die in the backlog without a reply, and the breaker only
observes replies - it can never be what moves traffic away. This is the shape of the recurring Windows CI failure of
WithRetry_FailsOverBetweenGroupsOnLoading (six attempts in twelve days, always 20 x 5000ms backlog timeouts): when the
heartbeat rather than the test's command met the first LOADING, nothing ever failed over.

LOADING now joins CircuitBreaker in the fast-path; the health check still decides where traffic goes, so a member whose
probe passes is kept (WithRetry_WhenFailoverNeverArrives_KeepsRetryingSameMember). New LoadingRerouteTests fails
without the change.
@mgravell
mgravell merged commit cb09290 into main Oct 22, 2026
4 of 5 checks passed
@mgravell
mgravell deleted the marc/group-loading-failover branch October 22, 2026 13:51
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