Skip to content
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

Fixed race condition in OnEnd and added a unit test #3951

Merged
merged 12 commits into from
Apr 14, 2023
4 changes: 2 additions & 2 deletions sdk/trace/simple_span_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {}

// OnEnd immediately exports a ReadOnlySpan.
func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) {
ssp.exporterMu.RLock()
defer ssp.exporterMu.RUnlock()
ssp.exporterMu.Lock()
Kaushal28 marked this conversation as resolved.
Show resolved Hide resolved
defer ssp.exporterMu.Unlock()
Kaushal28 marked this conversation as resolved.
Show resolved Hide resolved

if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() {
if err := ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}); err != nil {
Expand Down
31 changes: 31 additions & 0 deletions sdk/trace/simple_span_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package trace_test
import (
"context"
"errors"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -150,6 +151,36 @@ func TestSimpleSpanProcessorShutdownOnEndConcurrency(t *testing.T) {
<-done
}

func TestSimpleSpanProcessorShutdownOnEndRace(t *testing.T) {
pellared marked this conversation as resolved.
Show resolved Hide resolved
exporter := &testExporter{}
ssp := sdktrace.NewSimpleSpanProcessor(exporter)
tp := basicTracerProvider(t)
tp.RegisterSpanProcessor(ssp)

var wg sync.WaitGroup
wg.Add(2)
go func() {
_, span := tp.Tracer("test").Start(context.Background(), "A")
defer span.End()
Kaushal28 marked this conversation as resolved.
Show resolved Hide resolved
wg.Done()
Kaushal28 marked this conversation as resolved.
Show resolved Hide resolved
}()

go func() {
_, span := tp.Tracer("test").Start(context.Background(), "A")
defer span.End()
wg.Done()
}()

wg.Wait()

if err := ssp.Shutdown(context.Background()); err != nil {
t.Errorf("shutting the SimpleSpanProcessor down: %v", err)
Kaushal28 marked this conversation as resolved.
Show resolved Hide resolved
}
if !exporter.shutdown {
Kaushal28 marked this conversation as resolved.
Show resolved Hide resolved
t.Error("SimpleSpanProcessor.Shutdown did not shut down exporter")
}
}

func TestSimpleSpanProcessorShutdownHonorsContextDeadline(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
defer cancel()
Expand Down