mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-03-11 14:49:19 +02:00
trace: SpanFromContext and SpanContextFromContext make no allocs (#5049)
This commit is contained in:
parent
9184b10456
commit
6ff94ab620
@ -8,6 +8,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- `SpanFromContext` and `SpanContextFromContext` in `go.opentelemetry.io/otel/trace` no longer make a heap allocation when the passed context has no span. (#5049)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Clarify the documentation about equivalence guarantees for the `Set` and `Distinct` types in `go.opentelemetry.io/otel/attribute`. (#5027)
|
||||
|
@ -36,12 +36,12 @@ func ContextWithRemoteSpanContext(parent context.Context, rsc SpanContext) conte
|
||||
// performs no operations is returned.
|
||||
func SpanFromContext(ctx context.Context) Span {
|
||||
if ctx == nil {
|
||||
return noopSpan{}
|
||||
return noopSpanInstance
|
||||
}
|
||||
if span, ok := ctx.Value(currentSpanKey).(Span); ok {
|
||||
return span
|
||||
}
|
||||
return noopSpan{}
|
||||
return noopSpanInstance
|
||||
}
|
||||
|
||||
// SpanContextFromContext returns the current Span's SpanContext.
|
||||
|
@ -77,6 +77,16 @@ func TestSpanFromContext(t *testing.T) {
|
||||
// Ensure SpanContextFromContext is just
|
||||
// SpanFromContext(…).SpanContext().
|
||||
assert.Equal(t, tc.expectedSpan.SpanContext(), SpanContextFromContext(tc.context))
|
||||
|
||||
// Check that SpanFromContext does not produce any heap allocation.
|
||||
assert.Equal(t, 0.0, testing.AllocsPerRun(5, func() {
|
||||
SpanFromContext(tc.context)
|
||||
}), "SpanFromContext allocs")
|
||||
|
||||
// Check that SpanContextFromContext does not produce any heap allocation.
|
||||
assert.Equal(t, 0.0, testing.AllocsPerRun(5, func() {
|
||||
SpanContextFromContext(tc.context)
|
||||
}), "SpanContextFromContext allocs")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption
|
||||
span := SpanFromContext(ctx)
|
||||
if _, ok := span.(nonRecordingSpan); !ok {
|
||||
// span is likely already a noopSpan, but let's be sure
|
||||
span = noopSpan{}
|
||||
span = noopSpanInstance
|
||||
}
|
||||
return ContextWithSpan(ctx, span), span
|
||||
}
|
||||
@ -49,7 +49,7 @@ func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption
|
||||
// noopSpan is an implementation of Span that performs no operations.
|
||||
type noopSpan struct{ embedded.Span }
|
||||
|
||||
var _ Span = noopSpan{}
|
||||
var noopSpanInstance Span = noopSpan{}
|
||||
|
||||
// SpanContext returns an empty span context.
|
||||
func (noopSpan) SpanContext() SpanContext { return SpanContext{} }
|
||||
|
Loading…
x
Reference in New Issue
Block a user