[BUG] Draw the retry jitter from a per thread generator - #4399
Merged
marcalff merged 3 commits intoAug 10, 2026
Conversation
NextRetryTime multiplied the backoff by a sample from a function local static std::mt19937. Drawing from an engine advances its state, and every HttpClient runs its own background thread, so two clients retrying at the same time wrote the same engine. Thread safe initialisation of a function local static says nothing about using one. The engine is thread_local now and the distribution is an ordinary local, since sharing it bought nothing either. Each thread seeds its own from a temporary random_device, so the jitter is still per draw. Fixes open-telemetry#4398. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
Add the CHANGELOG entry now that the pull request has a number. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4399 +/- ##
=======================================
Coverage 81.92% 81.92%
=======================================
Files 494 494
Lines 19658 19658
=======================================
Hits 16103 16103
Misses 3555 3555
🚀 New features to boost your workflow:
|
Member
|
Do not auto-merge: Waiting for full ci to see the tsan tests. |
3 tasks
This was referenced Aug 11, 2026
Open
Open
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.
Fixes #4398, the first of the three things on it.
NextRetryTime()multiplies the backoff by a sample from a static engine:Drawing from an engine advances its state, so
dis(gen)is a write. EveryHttpClientruns its own background thread and each one calls this from its own retry loop, so two clients retrying at the same time write the samestd::mt19937. C++ guarantees the initialisation of a function local static is thread safe; it says nothing about using one afterwards.The engine becomes
thread_local, seeded per thread from a temporaryrandom_device. The distribution becomes an ordinary local, since it was only static out of habit and sharing it bought nothing.Evidence
NextRetryTime()is public and, unlikeIsRetryable(), its body is not behindENABLE_OTLP_RETRY_PREVIEW, so the static compiles into every build and a test can reach it without a retrying server. Two operations, two threads, 200 draws each:RetryJitterIsNotSharedAcrossThreadsunder TSANmainat f6e4818 with this test addedThe case passes on
maintoo, because a data race is not a functional failure. It is here so the sanitizer builds keep it fixed.What this does not touch
#4398 has two more items and neither is here. The retry deadline is redrawn every time
doRetrySessions()asks for it, so it is not a stable point in time, andIsRetryable()does not consider whether the request was cancelled. Both are tangled with the retry queue and with the teardown ordering in #4391, and both are worth deciding rather than guessing.Checks
23 of 23 in
curl_http_test. Clean underOTELCPP_MAINTAINER_MODE=ONandclang-format18.1.8. clang-tidy at zero delta againstmainunder the CI filters. IWYU clean on all three variants,all-options-abiv1,all-options-abiv1-previewandall-options-abiv2-preview, each checked against a deliberately unused include first so the zero means something.Related
#4392, #4394 and #4395 are open against the same two files. This one only touches
NextRetryTime, which none of them go near, so the production sides do not overlap. The test file is shared, and I will rebase whichever of them lands second.For significant contributions please make sure you have completed the following items:
CHANGELOG.mdupdated for non-trivial changes