Skip to content

Commit

Permalink
Fix issue #1490, apply same logic as in the SDK
Browse files Browse the repository at this point in the history
Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu committed Mar 10, 2021
1 parent 0fe561d commit 7d58d1c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 13 deletions.
38 changes: 25 additions & 13 deletions internal/global/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ import (
// All TracerProvider functionality is forwarded to a delegate once
// configured.
type tracerProvider struct {
mtx sync.Mutex
tracers []*tracer
tracers sync.Map
delegate atomic.Value
}

Expand All @@ -63,12 +62,11 @@ var _ trace.TracerProvider = &tracerProvider{}
// It is guaranteed by the caller that this happens only once.
func (p *tracerProvider) setDelegate(provider trace.TracerProvider) {
p.delegate.Store(provider)
p.mtx.Lock()
defer p.mtx.Unlock()

for _, t := range p.tracers {
t.setDelegate(provider)
}
p.tracers.Range(func(key, value interface{}) bool {
value.(*tracer).setDelegate(provider)
p.tracers.Delete(key)
return true
})
}

// Tracer implements TracerProvider.
Expand All @@ -78,12 +76,26 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
return delegate.(trace.TracerProvider).Tracer(name, opts...)
}

p.mtx.Lock()
defer p.mtx.Unlock()
key := createKey(name, opts...)
if val, ok := p.tracers.Load(key); ok {
return val.(*tracer)
}

// Value not present, we cannot be sure that there is not any other concurrent
t, _ := p.tracers.LoadOrStore(key, &tracer{name: name, opts: opts})
return t.(*tracer)
}

type il struct {
name string
version string
}

t := &tracer{name: name, opts: opts}
p.tracers = append(p.tracers, t)
return t
func createKey(name string, opts ...trace.TracerOption) il {
return il{
name: name,
version: trace.NewTracerConfig(opts...).InstrumentationVersion,
}
}

// tracer is a placeholder for a trace.Tracer.
Expand Down
19 changes: 19 additions & 0 deletions internal/global/trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ func TestTraceProviderDelegates(t *testing.T) {
assert.True(t, called, "expected configured TraceProvider to be called")
}

func TestTraceProviderDelegates_SameInstance(t *testing.T) {
global.ResetForTest()

// Retrieve the placeholder TracerProvider.
gtp := otel.GetTracerProvider()

tracer := gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz"))
assert.Same(t, tracer, gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz")))
assert.Same(t, tracer, gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz")))

otel.SetTracerProvider(fnTracerProvider{
tracer: func(name string, opts ...trace.TracerOption) trace.Tracer {
return trace.NewNoopTracerProvider().Tracer("")
},
})

assert.NotSame(t, tracer, gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz")))
}

func TestTraceProviderDelegates_MultiGoRoutines(t *testing.T) {
global.ResetForTest()

Expand Down

0 comments on commit 7d58d1c

Please sign in to comment.