diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f4a44b60aa..ec9f9c49c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm This changes it to make `SamplingParameters` conform with the OpenTelemetry specification. (#1749) - Modify `BatchSpanProcessor.ForceFlush` to abort after timeout/cancellation. (#1757) - Improve OTLP/gRPC exporter connection errors. (#1737) +- Make `ExportSpans` in Jaeger Exporter honor context deadline. (#1773) ### Removed diff --git a/exporters/trace/jaeger/jaeger.go b/exporters/trace/jaeger/jaeger.go index e4d45afcecd..7eb6b282305 100644 --- a/exporters/trace/jaeger/jaeger.go +++ b/exporters/trace/jaeger/jaeger.go @@ -217,11 +217,17 @@ func (e *Exporter) ExportSpans(ctx context.Context, ss []*export.SpanSnapshot) e for _, span := range ss { // TODO(jbd): Handle oversized bundlers. - err := e.bundler.Add(span, 1) + err := e.bundler.AddWait(ctx, span, 1) if err != nil { return fmt.Errorf("failed to bundle %q: %w", span.Name, err) } + select { + case <-ctx.Done(): + return ctx.Err() + default: + } } + return nil } diff --git a/exporters/trace/jaeger/jaeger_test.go b/exporters/trace/jaeger/jaeger_test.go index e7cbd54660c..0666f17af1d 100644 --- a/exporters/trace/jaeger/jaeger_test.go +++ b/exporters/trace/jaeger/jaeger_test.go @@ -649,6 +649,67 @@ func TestErrorOnExportShutdownExporter(t *testing.T) { assert.NoError(t, e.ExportSpans(context.Background(), nil)) } +func TestExporterExportSpansHonorsCancel(t *testing.T) { + e, err := NewRawExporter(withTestCollectorEndpoint()) + require.NoError(t, err) + now := time.Now() + ss := []*export.SpanSnapshot{ + { + Name: "s1", + Resource: resource.NewWithAttributes( + semconv.ServiceNameKey.String("name"), + attribute.Key("r1").String("v1"), + ), + StartTime: now, + EndTime: now, + }, + { + Name: "s2", + Resource: resource.NewWithAttributes( + semconv.ServiceNameKey.String("name"), + attribute.Key("r2").String("v2"), + ), + StartTime: now, + EndTime: now, + }, + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + assert.EqualError(t, e.ExportSpans(ctx, ss), context.Canceled.Error()) +} + +func TestExporterExportSpansHonorsTimeout(t *testing.T) { + e, err := NewRawExporter(withTestCollectorEndpoint()) + require.NoError(t, err) + now := time.Now() + ss := []*export.SpanSnapshot{ + { + Name: "s1", + Resource: resource.NewWithAttributes( + semconv.ServiceNameKey.String("name"), + attribute.Key("r1").String("v1"), + ), + StartTime: now, + EndTime: now, + }, + { + Name: "s2", + Resource: resource.NewWithAttributes( + semconv.ServiceNameKey.String("name"), + attribute.Key("r2").String("v2"), + ), + StartTime: now, + EndTime: now, + }, + } + ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond) + defer cancel() + <-ctx.Done() + + assert.EqualError(t, e.ExportSpans(ctx, ss), context.DeadlineExceeded.Error()) +} + func TestJaegerBatchList(t *testing.T) { newString := func(value string) *string { return &value