fix(ddtrace/tracer): classify ENOTCONN as transient and raise stale-conn retry budget#4908
Conversation
…udget
On Darwin, the stale-idle UDS write race surfaces as syscall.ENOTCONN
("socket is not connected") rather than the Linux-typical EPIPE or
ECONNRESET. isTransientConnError did not recognise ENOTCONN, so
doWithStaleConnRetry returned the error immediately without retrying,
causing TestUDSTransportRecoversFromStaleIdleConn to flake at ~1.25%/run
on macOS CI.
Two changes:
- Add errors.Is(err, syscall.ENOTCONN) to isTransientConnError alongside
EPIPE/ECONNRESET/ECONNABORTED, and add the "socket is not connected"
string fallback for Windows WSAENOTCONN parity.
- Raise staleConnRetryAttempts from 3 to 6 (7 total attempts) to absorb
the Linux net.ErrClosed burst-exhaustion that was the originally-
reported CI failure mode.
Verified: 0/80 batches failed (count=10 each) after the fix vs 10/80
before; race detector clean; full transport regression set green.
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 4442e9b | Docs | Datadog PR Page | Give us feedback! |
BenchmarksBenchmark execution time: 2026-06-18 15:43:57 Comparing candidate commit 4442e9b in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 297 metrics, 2 unstable metrics, 1 flaky benchmarks without significant changes.
|
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
What does this PR do
syscall.ENOTCONNtoisTransientConnError(alongsideEPIPE/ECONNRESET/ECONNABORTED/net.ErrClosed), and add a"socket is not connected"string fallback for WindowsWSAENOTCONNparity.staleConnRetryAttemptsfrom3→6(7 total attempts) to absorb the Linuxnet.ErrClosedburst-exhaustion path.Motivation
TestUDSTransportRecoversFromStaleIdleConnwas flaking at ~1.25%/run on macOS CI (#4809 introduced the test and the retry fix). The flake had two distinct failure modes:macOS (dominant, reproduced): On Darwin, the same stale-idle UDS write race that produces
EPIPEon Linux surfaces instead asENOTCONN("socket is not connected").isTransientConnErrordid not recogniseENOTCONN, sodoWithStaleConnRetryreturned immediately without retrying and the request was lost.Linux (rarer, the originally-reported CI error):
net.ErrClosedis correctly classified and retried, but under the 400-request synthetic burst the idle pool can keep handing out stale conns, occasionally exhausting all 4 original attempts before landing on a fresh connection.Verification
Reproduced baseline flake with a compiled test binary: 10/80 batches failed (count=10 each), 100% ENOTCONN. After the fix: 0/80 batches failed.
go test -race -run 'TestUDSTransportRecoversFromStaleIdleConn' -count=20 ./ddtrace/tracer/— cleango build ./ddtrace/tracer/... && go vet ./ddtrace/tracer/...— clean