From c82dbddc3107393287c829677c6ef8dfaf737af5 Mon Sep 17 00:00:00 2001 From: Ziqi Zhao Date: Wed, 4 Jan 2023 01:51:56 +0800 Subject: [PATCH] TracerProvider shutdown release resources (#3551) * TracerProvider shutdown release resources Signed-off-by: Ziqi Zhao * add changelog Signed-off-by: Ziqi Zhao * Update CHANGELOG.md Co-authored-by: David Ashpole * prevent registered span processors after shutdown Signed-off-by: Ziqi Zhao * Update CHANGELOG.md Signed-off-by: Ziqi Zhao Co-authored-by: David Ashpole Co-authored-by: Chester Cheung Co-authored-by: Tyler Yahn --- CHANGELOG.md | 1 + sdk/trace/provider.go | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff6d25fbe11..e444b1fa17e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/sdk/trace/provider.go b/sdk/trace/provider.go index 327b8b41638..201c1781700 100644 --- a/sdk/trace/provider.go +++ b/sdk/trace/provider.go @@ -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. @@ -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)) @@ -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 @@ -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 { @@ -255,6 +267,7 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error { } } } + p.spanProcessors.Store(spanProcessorStates{}) return retErr }