summaryrefslogtreecommitdiff
path: root/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.opentelemetry.io/otel/sdk/trace/provider.go')
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/provider.go99
1 files changed, 30 insertions, 69 deletions
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
index 0a018c14d..201c17817 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
@@ -75,9 +75,8 @@ func (cfg tracerProviderConfig) MarshalLog() interface{} {
type TracerProvider struct {
mu sync.Mutex
namedTracer map[instrumentation.Scope]*tracer
- spanProcessors atomic.Pointer[spanProcessorStates]
-
- isShutdown atomic.Bool
+ 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.
@@ -120,11 +119,11 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider {
}
global.Info("TracerProvider created", "config", o)
- spss := make(spanProcessorStates, 0, len(o.processors))
+ spss := spanProcessorStates{}
for _, sp := range o.processors {
spss = append(spss, newSpanProcessorState(sp))
}
- tp.spanProcessors.Store(&spss)
+ tp.spanProcessors.Store(spss)
return tp
}
@@ -137,11 +136,10 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider {
//
// This method is safe to be called concurrently.
func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
- // This check happens before the mutex is acquired to avoid deadlocking if Tracer() is called from within Shutdown().
- if p.isShutdown.Load() {
- return trace.NewNoopTracerProvider().Tracer(name, opts...)
- }
c := trace.NewTracerConfig(opts...)
+
+ p.mu.Lock()
+ defer p.mu.Unlock()
if name == "" {
name = defaultTracerName
}
@@ -150,74 +148,44 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
Version: c.InstrumentationVersion(),
SchemaURL: c.SchemaURL(),
}
-
- t, ok := func() (trace.Tracer, bool) {
- p.mu.Lock()
- defer p.mu.Unlock()
- // Must check the flag after acquiring the mutex to avoid returning a valid tracer if Shutdown() ran
- // after the first check above but before we acquired the mutex.
- if p.isShutdown.Load() {
- return trace.NewNoopTracerProvider().Tracer(name, opts...), true
- }
- t, ok := p.namedTracer[is]
- if !ok {
- t = &tracer{
- provider: p,
- instrumentationScope: is,
- }
- p.namedTracer[is] = t
- }
- return t, ok
- }()
+ t, ok := p.namedTracer[is]
if !ok {
- // This code is outside the mutex to not hold the lock while calling third party logging code:
- // - That code may do slow things like I/O, which would prolong the duration the lock is held,
- // slowing down all tracing consumers.
- // - Logging code may be instrumented with tracing and deadlock because it could try
- // acquiring the same non-reentrant mutex.
- global.Info("Tracer created", "name", name, "version", is.Version, "schemaURL", is.SchemaURL)
+ t = &tracer{
+ provider: p,
+ instrumentationScope: is,
+ }
+ p.namedTracer[is] = t
+ global.Info("Tracer created", "name", name, "version", c.InstrumentationVersion(), "schemaURL", c.SchemaURL())
}
return t
}
// RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors.
func (p *TracerProvider) RegisterSpanProcessor(sp SpanProcessor) {
- // This check prevents calls during a shutdown.
- if p.isShutdown.Load() {
- return
- }
p.mu.Lock()
defer p.mu.Unlock()
- // This check prevents calls after a shutdown.
- if p.isShutdown.Load() {
+ if p.isShutdown {
return
}
-
- current := p.getSpanProcessors()
- newSPS := make(spanProcessorStates, 0, len(current)+1)
- newSPS = append(newSPS, current...)
+ newSPS := spanProcessorStates{}
+ newSPS = append(newSPS, p.spanProcessors.Load().(spanProcessorStates)...)
newSPS = append(newSPS, newSpanProcessorState(sp))
- p.spanProcessors.Store(&newSPS)
+ p.spanProcessors.Store(newSPS)
}
// UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors.
func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) {
- // This check prevents calls during a shutdown.
- if p.isShutdown.Load() {
- return
- }
p.mu.Lock()
defer p.mu.Unlock()
- // This check prevents calls after a shutdown.
- if p.isShutdown.Load() {
+ if p.isShutdown {
return
}
- old := p.getSpanProcessors()
+ old := p.spanProcessors.Load().(spanProcessorStates)
if len(old) == 0 {
return
}
- spss := make(spanProcessorStates, len(old))
- copy(spss, old)
+ spss := spanProcessorStates{}
+ spss = append(spss, old...)
// stop the span processor if it is started and remove it from the list
var stopOnce *spanProcessorState
@@ -241,13 +209,13 @@ func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) {
spss[len(spss)-1] = nil
spss = spss[:len(spss)-1]
- p.spanProcessors.Store(&spss)
+ p.spanProcessors.Store(spss)
}
// ForceFlush immediately exports all spans that have not yet been exported for
// all the registered span processors.
func (p *TracerProvider) ForceFlush(ctx context.Context) error {
- spss := p.getSpanProcessors()
+ spss := p.spanProcessors.Load().(spanProcessorStates)
if len(spss) == 0 {
return nil
}
@@ -268,21 +236,18 @@ func (p *TracerProvider) ForceFlush(ctx context.Context) error {
// Shutdown shuts down TracerProvider. All registered span processors are shut down
// in the order they were registered and any held computational resources are released.
-// After Shutdown is called, all methods are no-ops.
func (p *TracerProvider) Shutdown(ctx context.Context) error {
- // This check prevents deadlocks in case of recursive shutdown.
- if p.isShutdown.Load() {
+ spss := p.spanProcessors.Load().(spanProcessorStates)
+ if len(spss) == 0 {
return nil
}
+
p.mu.Lock()
defer p.mu.Unlock()
- // This check prevents calls after a shutdown has already been done concurrently.
- if !p.isShutdown.CompareAndSwap(false, true) { // did toggle?
- return nil
- }
+ p.isShutdown = true
var retErr error
- for _, sps := range p.getSpanProcessors() {
+ for _, sps := range spss {
select {
case <-ctx.Done():
return ctx.Err()
@@ -302,14 +267,10 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error {
}
}
}
- p.spanProcessors.Store(&spanProcessorStates{})
+ p.spanProcessors.Store(spanProcessorStates{})
return retErr
}
-func (p *TracerProvider) getSpanProcessors() spanProcessorStates {
- return *(p.spanProcessors.Load())
-}
-
// TracerProviderOption configures a TracerProvider.
type TracerProviderOption interface {
apply(tracerProviderConfig) tracerProviderConfig