-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Guarantee ForceFlush of BatchSpanProcessor will export all ended spans #2080
Comments
yes, seems it is a a multi-thread bug, some data may still in opentelemetry-go/sdk/trace/batch_span_processor.go Lines 250 to 252 in 7a0cee7
|
I guess the issue is caused by
span is at |
If anyone else hits this issue I was able to successfully get the example above working by using The issue is we have two buffers the
The former option seems the most go like, but does increase the complexity of the class a bit, especially during shutdown to ensure nothing deadlocks waiting on a flush. |
What about something like this? Define the following type: type forceFlushSpan struct {
flushed chan struct{}
} Then in ForceFlush() before we call export spans add this logic: flushCh := make(chan struct{})
select {
case bsp.queue <- forceFlushSpan{flushCh}:
case <-ctx.Done():
return ctx.Err()
}
select {
case <-flushCh:
// Processed any items in queue prior to ForceFlush being called
case <-ctx.Done():
return ctx.Err()
} Then in if ffs, ok := sd.(forceFlushSpan); ok {
close(ffs.flushed)
return
} This way we'll ensure that anything in the queue at the time ForceFlush() is called will be written out but we don't get into complex race conditions if traces continue to come through. The main negative of this approach is another implementation of ReadOnlySpan (with a lot of boilerplate). |
* Empty queued spans when ForceFlush called Update the implementation of ForceFlush() to first ensure that all spans which are queued are added to the batch before calling export spans. Create a small ReadOnlySpan implementation which can be used as a marker that ForceFlush has been invoked and used to notify when all spans are ready to be exported. Fixes #2080. * Add a changelog entry. * Update CHANGELOG.md Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> * Update sdk/trace/batch_span_processor.go Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> * Improve test case to verify multiple flushes. * Refactor code to use enqueue. * Be more defensive on waiting for queue. Update the handling of the force flush span so we only wait on the channel if we were able to enqueue the span to the queue. * Fix linter. Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
Problem Statement
Currently calling ForceFlush on a BatchSpanProcessor will export all spans which have been ended AND consumed into the BSP's batch. However, spans which have been ended before a call to ForceFlush are not guaranteed to be consumed into the batch and therefore may or may not be exported by ForceFlush as desired.
Proposed Solution
I would like ForceFlush to ensure any ended spans are indeed exported following a call to ForceFlush.
I have attempted to modify ForceFlush myself to process the queue before exporting but have achieved only mixed results.
Prior Art
Using runtime.Gosched() either within ForceFlush or in user code before calling ForceFlush to yield execution and allow consumption to occur naturally is very likely to populate the batch with any ended spans, but is not guaranteed to do so.
Additional Context
A simple test case which would pass after such a change is as follows:
Intuitively I would already expect this test case to pass, however, current behavior of the BatchSpanProcessor causes the result of this test case to be inconsistent.
The text was updated successfully, but these errors were encountered: