fix(client): eliminate resolver probation starvation in LossThenLatency balancing strategy - #206
Open
taskkillstar wants to merge 2 commits into
Open
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Zero-RTT resolvers can still starve after the actual seeded reactivation flow.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates resolver scoring to use available packet and RTT samples immediately, reducing probation starvation.
Changes:
- Removes five-sample scoring thresholds.
- Adds a Strategy 6 regression test.
File summaries
| File | Description |
|---|---|
internal/client/balancer.go |
Revises loss, latency, and signal scoring. |
internal/client/balancer_test.go |
Tests low-sample resolver selection. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
Summary of Changes
This PR fixes a starvation / deadlock issue in the client balancer where newly reactivated or low-traffic resolvers are permanently locked out of selection when using Strategy 6 (
BalancingLossThenLatency) or scoring strategies.Root Cause Analysis
In upstream
internal/client/balancer.go:The 5-Packet Probation Penalty:
In
lossScoreLocked(idx int):Any resolver with
sent < 5is assigned a synthetic loss penalty score of200.Candidate Filtering in Strategy 6 (
lossThenLatencyCandidatesLocked):Strategy 6 computes the loss cutoff relative to the best resolver in the pool:
bestLossbecomes0.25(0 + 25 = 25).sent < 5(e.g. newly reactivated from health checks or standby) haslossScore = 200.200 > 25, the resolver is strictly discarded (cand.loss > lossCutoff).Deadlock / Starvation:
Because the unproven resolver is filtered out of selection, it is never routed any tunnel packets. Its
sentcounter never reaches5, causing it to remain trapped in probation forever while traffic continues piling onto established resolvers even if their latency degrades.Latency Floor in
$\mu s$ ) when $1 \le count < 5$ .
latencyScoreLocked:latencyScoreLockedsimilarly returned999000(count < 5, ignoring valid RTT measurements for resolvers withChanges Made
Dynamic Loss Calculation (
lossScoreLocked):sent < 5return of200.sent == 0orlost == 0, return0(clean/unpenalized).sent > 0, return(lost * 1000) / sent.Dynamic Latency Calculation (
latencyScoreLocked):count > 0, computesum / countusing the actual RTT observations.999000ifcount == 0(no samples recorded).Signal Checks (
hasLossSignalLocked/hasLatencySignalLocked):sent > 0andcount > 0so runtime statistics take effect as soon as real samples are available.Unit Test:
TestBalancerLossThenLatency_NoProbationStarvationininternal/client/balancer_test.goto ensure a newly activated low-latency resolver with fewer than 5 packets is successfully selected over an established high-latency resolver.Verification
go test -v -run TestBalancer ./internal/client/...