Repository navigation
fix(outboundgroup): exclude caller cancellation from TCP failure checks - #3437
Open
polaris-arch wants to merge 2 commits into
Open
polaris-arch wants to merge 2 commits into
polaris-arch wants to merge 2 commits into
Conversation
This was referenced Nov 9, 2026
polaris-arch
marked this pull request as draft
November 9, 2026 11:43
polaris-arch
marked this pull request as ready for review
November 9, 2026 12:26
polaris-arch
marked this pull request as draft
November 9, 2026 14:23
polaris-arch
marked this pull request as ready for review
November 10, 2026 14:26
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.
Exclude errors observed after caller cancellation from TCP group-failure accounting in fallback, url-test and load-balance, including deferred first
Write/WriteBuffer. Preserve deadline failures, live-context transport failures and failures attributed before a later cancellation.Concrete bugs and normal-path reachability
getGroupDelay→ request-derived context →GroupBase.URLTest→ child proxyURLTest→DialContext. With nested groups, a canceled HTTP request can therefore reach an affected child group. The ordinary tunnel's current background-derived dial context does not itself translate frontend closure into caller cancellation; fix(tunnel): cancel preparation on native frontend closure #3438 adds that separate source. No production incidence rate or controller-to-real-node end-to-end reproduction is claimed here.failedTimeswithout a common lock. Parallelconnection refusedhandling can also race the old load-then-store health-check guard. These are source-identified concurrency defects under concurrent connections, independent of caller cancellation. The same new public-path fixture now reproduces a race in unchanged Alpha betweenonDialSuccessand asynchronousonDialFailed/counter reset, specifically onfailedTimes. The candidate passes the same fixture under-race; this is separate evidence from the 9 canceled-attribution cases.Source: controller request context, proxy URLTest dial, old accounting.
Protect counters/resets consistently and claim health checks with compare-and-swap. Moving health-check work outside the counter mutex is required by that locking change; no pre-existing deadlock is claimed from that movement alone.
Attribution policy:
ctx.Err() == context.Canceledis sampled before asynchronous accounting. This is not proof that the transport error was caused by cancellation or that the node is healthy: a genuine error coinciding with cancellation can also be excluded.DeadlineExceededremains countable; cancellation after attribution does not erase the failure.Executable reproduction and observed result
Run in a disposable checkout with Go 1.26.10 (the recorded validation toolchain):
To test the same relevant fixture against unchanged Alpha:
The baseline command is expected to fail an assertion, not fail to compile.
The baseline fixture is intentionally truncated before candidate-only helper tests and drops the then-unused
timeimport, matching the archived validation procedure; the attribution test itself is unchanged.The copied prefix also includes
TestLifecycleGroupConcurrentPublicPaths, which alternates successful first writes and failed dials through public group methods. Run it unchanged on the baseline:Recorded comparison: Alpha reports
WARNING: DATA RACEonfailedTimesingroupbase.go; heade8ffb994passes. Providers/leaf outcomes are synthetic, but the counter is accessed via the public concurrent dial/write paths, not directly by the fixture.Fault injection and defensive coverage
The leaf proxy, socket error, provider and cancellation timing are synthetic fixtures; no actual node is probed.
synctest.Waitdrains accounting before negative assertions. Nested-group, ordering, exemptions and held-provider concurrency tests are boundary coverage. These counts are test coverage, not production failure frequency or saved real probes.Focused/race tests, complete default/with_gvisor suites, vet and Windows/macOS package compilation passed in standalone validation; combined validation covers the tunnel consumers. The generic timeout correction #3439 can be reviewed separately; native cancellation integration should retain this attribution policy.
Current head
e8ffb994passes focused/race, full default/with_gvisor, vet and Windows/macOS compilation in standalone validation; final combined validation covers its tunnel consumers. The head delta adds tests only.