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

TracerProvider shutdown release resources #3551

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add `Producer` interface and `Reader.RegisterProducer(Producer)` to `go.opentelemetry.io/otel/sdk/metric` to enable external metric Producers. (#3524)
- Add `NewMetricProducer` to `go.opentelemetry.io/otel/bridge/opencensus`, which can be used to pass OpenCensus metrics to an OpenTelemetry Reader. (#3541)
- Global logger uses an atomic value instead of a mutex. (#3545)
- The `Shutdown` method of the `"go.opentelemetry.io/otel/sdk/trace".TracerProvider` releases all computational resources when called the first time. (#3551)
- `traceIDRatioSampler` (given by `TraceIDRatioBased(float64)`) now uses the rightmost bits for sampling decisions,
fixing random sampling when using ID generators like `xray.IDGenerator`
and increasing parity with other language implementations. (#3557)
Expand Down
15 changes: 14 additions & 1 deletion sdk/trace/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type TracerProvider struct {
mu sync.Mutex
namedTracer map[instrumentation.Scope]*tracer
spanProcessors atomic.Value
isShutdown bool

// These fields are not protected by the lock mu. They are assumed to be
// immutable after creation of the TracerProvider.
Expand Down Expand Up @@ -163,6 +164,9 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
func (p *TracerProvider) RegisterSpanProcessor(sp SpanProcessor) {
p.mu.Lock()
defer p.mu.Unlock()
if p.isShutdown {
return
}
newSPS := spanProcessorStates{}
newSPS = append(newSPS, p.spanProcessors.Load().(spanProcessorStates)...)
newSPS = append(newSPS, newSpanProcessorState(sp))
Expand All @@ -173,6 +177,9 @@ func (p *TracerProvider) RegisterSpanProcessor(sp SpanProcessor) {
func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) {
p.mu.Lock()
defer p.mu.Unlock()
if p.isShutdown {
return
}
old := p.spanProcessors.Load().(spanProcessorStates)
if len(old) == 0 {
return
Expand Down Expand Up @@ -227,13 +234,18 @@ func (p *TracerProvider) ForceFlush(ctx context.Context) error {
return nil
}

// Shutdown shuts down the span processors in the order they were registered.
// Shutdown shuts down TracerProvider. All registered span processors are shut down
// in the order they were registered and any held computational resources are released.
func (p *TracerProvider) Shutdown(ctx context.Context) error {
spss := p.spanProcessors.Load().(spanProcessorStates)
if len(spss) == 0 {
return nil
}

p.mu.Lock()
defer p.mu.Unlock()
p.isShutdown = true

var retErr error
for _, sps := range spss {
select {
Expand All @@ -255,6 +267,7 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error {
}
}
}
p.spanProcessors.Store(spanProcessorStates{})
fatsheep9146 marked this conversation as resolved.
Show resolved Hide resolved
return retErr
}

Expand Down