feat(llmobs): add internal FlushSync function#4695
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files
🚀 New features to boost your workflow:
|
🎉 All green!❄️ No new flaky tests detected 🎯 Code Coverage (details) 🔗 Commit SHA: 6812c31 | Docs | Datadog PR Page | Give us feedback! |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 66532d582f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
| case l.flushNowCh <- done: | ||
| <-done |
There was a problem hiding this comment.
Return from FlushSync when the worker is stopped
When FlushSync is called on an LLMObs pointer after Stop (or races with Stop), stopCh is closed but the send to the buffered flushNowCh can also be selected when the buffer is empty. In that branch there is no worker left to receive the done channel, so the following <-done blocks forever instead of returning; check the stopped state before enqueueing the sync flush.
Useful? React with 👍 / 👎.
BenchmarksBenchmark execution time: 2026-05-05 13:58:43 Comparing candidate commit 6812c31 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 176 metrics, 0 unstable metrics.
|
FlushSync correctly blocks until batchSend completes, but the testtracer mock pushes parsed spans through an unbuffered payloadChan that is drained by collectPayloads in a separate goroutine. The unbuffered send synchronizes only the value transfer; the recorder's lock+append can lag behind FlushSync's return, leaving SentPayloads empty. Use the existing WaitForLLMObsSpans helper, which is the pattern used by the other tests in this file that read recorded payloads. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c6b506335
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
kakkoyun
left a comment
There was a problem hiding this comment.
LGTM.
I have raised only two minor issues.
| params := l.clearBuffersNonLocked() | ||
| l.wg.Go(func() { | ||
| l.batchSend(params) | ||
| if done != nil { |
There was a problem hiding this comment.
nit: We can call this wrap with defer, in case batchSend panics.
There was a problem hiding this comment.
Without recover() the defer is not gonna help much in that case here as the program would still crash in case of panic. batchSend is not expected to panic, so if it does I would prefer not to silence it here (in general I think that would look like the try catch pattern from other languages that I would like to avoid if possible 🙏 )
There was a problem hiding this comment.
Even without a recover, defers would be executed. It's a guaranteed way to making sure the channel is closed. So it is not about being silent but about making sure we unblock other goroutine wait on this channel if something goes wrong with batchSend. We can have it defensively or as you said if we don't expect batchSend call-chain to never fail, we can accept the state as is.
|
@rarguelloF @kakkoyun Should we admin merge this? |
What does this PR do?
Adds a
FlushSyncfunction that does the same as the existingFlushbut does not return until payloads have been actually sent.This is a requirement for #4512
Motivation
Reviewer's Checklist
make lintlocally.make testlocally.make generatelocally.make fix-moduleslocally.Unsure? Have a question? Request a review!