diff --git a/CHANGELOG.md b/CHANGELOG.md index 691ed9e8c4f..e07b19348af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - If a Reader's AggregationSelector return nil or DefaultAggregation the pipeline will use the default aggregation. (#4350) - Log a suggested view that fixes instrument conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4349) - Fix possible panic, deadlock and race condition in batch span processor in `go.opentelemetry.io/otel/sdk/trace`. (#4353) +- Improve context cancelation handling in batch span processor's `ForceFlush` in `go.opentelemetry.io/otel/sdk/trace`. (#4369) ## [1.16.0/0.39.0] 2023-05-18 diff --git a/sdk/trace/batch_span_processor.go b/sdk/trace/batch_span_processor.go index 5922048fe62..c9c7effbf38 100644 --- a/sdk/trace/batch_span_processor.go +++ b/sdk/trace/batch_span_processor.go @@ -187,6 +187,11 @@ func (f forceFlushSpan) SpanContext() trace.SpanContext { // ForceFlush exports all ended spans that have not yet been exported. func (bsp *batchSpanProcessor) ForceFlush(ctx context.Context) error { + // Interrupt if context is already canceled. + if err := ctx.Err(); err != nil { + return err + } + // Do nothing after Shutdown. if bsp.stopped.Load() { return nil diff --git a/sdk/trace/batch_span_processor_test.go b/sdk/trace/batch_span_processor_test.go index d4a5c2976a5..b8706ce463e 100644 --- a/sdk/trace/batch_span_processor_test.go +++ b/sdk/trace/batch_span_processor_test.go @@ -560,6 +560,18 @@ func TestBatchSpanProcessorForceFlushCancellation(t *testing.T) { } } +func TestBatchSpanProcessorForceFlushTimeout(t *testing.T) { + // Add timeout to context to test deadline + ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond) + defer cancel() + <-ctx.Done() + + bsp := sdktrace.NewBatchSpanProcessor(indefiniteExporter{}) + if got, want := bsp.ForceFlush(ctx), context.DeadlineExceeded; !errors.Is(got, want) { + t.Errorf("expected %q error, got %v", want, got) + } +} + func TestBatchSpanProcessorForceFlushQueuedSpans(t *testing.T) { ctx := context.Background()