Skip to content

Commit

Permalink
TracerProvider doesn't allow to register a SpanProcessor after shutdo…
Browse files Browse the repository at this point in the history
…wn (#3845)
  • Loading branch information
ash2k authored Mar 22, 2023
1 parent 282a47e commit e4cc478
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Rename `Float64ObserverOption` to `Float64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)
- The internal logging changes the verbosity level of info to `V(4)`, the verbosity level of debug to `V(8)`. (#3900)

### Fixed

- `TracerProvider` consistently doesn't allow to register a `SpanProcessor` after shutdown. (#3845)

### Removed

- The deprecated `go.opentelemetry.io/otel/metric/global` package is removed. (#3829)
Expand Down
9 changes: 4 additions & 5 deletions sdk/trace/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,13 @@ 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.
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()
if p.isShutdown {
return nil
}
p.isShutdown = true
spss := p.spanProcessors.Load().(spanProcessorStates)

var retErr error
for _, sps := range spss {
Expand Down
31 changes: 31 additions & 0 deletions sdk/trace/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func TestForceFlushAndShutdownTraceProviderWithoutProcessor(t *testing.T) {
stp := NewTracerProvider()
assert.NoError(t, stp.ForceFlush(context.Background()))
assert.NoError(t, stp.Shutdown(context.Background()))
assert.True(t, stp.isShutdown)
}

func TestShutdownTraceProvider(t *testing.T) {
Expand All @@ -60,6 +61,7 @@ func TestShutdownTraceProvider(t *testing.T) {
assert.NoError(t, stp.ForceFlush(context.Background()))
assert.True(t, sp.flushed, "error ForceFlush basicSpanProcessor")
assert.NoError(t, stp.Shutdown(context.Background()))
assert.True(t, stp.isShutdown)
assert.True(t, sp.closed, "error Shutdown basicSpanProcessor")
}

Expand All @@ -74,6 +76,7 @@ func TestFailedProcessorShutdown(t *testing.T) {
err := stp.Shutdown(context.Background())
assert.Error(t, err)
assert.Equal(t, err, spErr)
assert.True(t, stp.isShutdown)
}

func TestFailedProcessorsShutdown(t *testing.T) {
Expand All @@ -94,6 +97,7 @@ func TestFailedProcessorsShutdown(t *testing.T) {
assert.EqualError(t, err, "basic span processor shutdown failure1; basic span processor shutdown failure2")
assert.True(t, sp1.closed)
assert.True(t, sp2.closed)
assert.True(t, stp.isShutdown)
}

func TestFailedProcessorShutdownInUnregister(t *testing.T) {
Expand All @@ -110,6 +114,7 @@ func TestFailedProcessorShutdownInUnregister(t *testing.T) {

err := stp.Shutdown(context.Background())
assert.NoError(t, err)
assert.True(t, stp.isShutdown)
}

func TestSchemaURL(t *testing.T) {
Expand All @@ -122,6 +127,32 @@ func TestSchemaURL(t *testing.T) {
assert.EqualValues(t, schemaURL, tracerStruct.instrumentationScope.SchemaURL)
}

func TestRegisterAfterShutdownWithoutProcessors(t *testing.T) {
stp := NewTracerProvider()
err := stp.Shutdown(context.Background())
assert.NoError(t, err)
assert.True(t, stp.isShutdown)

sp := &basicSpanProcessor{}
stp.RegisterSpanProcessor(sp) // no-op
assert.Empty(t, stp.spanProcessors.Load().(spanProcessorStates))
}

func TestRegisterAfterShutdownWithProcessors(t *testing.T) {
stp := NewTracerProvider()
sp1 := &basicSpanProcessor{}

stp.RegisterSpanProcessor(sp1)
err := stp.Shutdown(context.Background())
assert.NoError(t, err)
assert.True(t, stp.isShutdown)
assert.Empty(t, stp.spanProcessors.Load().(spanProcessorStates))

sp2 := &basicSpanProcessor{}
stp.RegisterSpanProcessor(sp2) // no-op
assert.Empty(t, stp.spanProcessors.Load().(spanProcessorStates))
}

func TestTracerProviderSamplerConfigFromEnv(t *testing.T) {
type testCase struct {
sampler string
Expand Down

0 comments on commit e4cc478

Please sign in to comment.