Skip to content

Commit 221b2ac

Browse files
authored
Fix race condition on GetSpan and guard transport on Close (#1044)
1 parent d20dadd commit 221b2ac

3 files changed

Lines changed: 31 additions & 3 deletions

File tree

scope.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ func (scope *Scope) SetPropagationContext(propagationContext PropagationContext)
304304

305305
// GetSpan returns the span from the current scope.
306306
func (scope *Scope) GetSpan() *Span {
307+
scope.mu.RLock()
308+
defer scope.mu.RUnlock()
309+
307310
return scope.span
308311
}
309312

transport.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ type HTTPTransport struct {
303303
// current in-flight items and starts a new batch for subsequent events.
304304
buffer chan batch
305305

306-
start sync.Once
306+
startOnce sync.Once
307+
closeOnce sync.Once
307308

308309
// Size of the transport buffer. Defaults to 30.
309310
BufferSize int
@@ -364,7 +365,7 @@ func (t *HTTPTransport) Configure(options ClientOptions) {
364365
}
365366
}
366367

367-
t.start.Do(func() {
368+
t.startOnce.Do(func() {
368369
go t.worker()
369370
})
370371
}
@@ -506,7 +507,9 @@ fail:
506507
// Close should be called after Flush and before terminating the program
507508
// otherwise some events may be lost.
508509
func (t *HTTPTransport) Close() {
509-
close(t.done)
510+
t.closeOnce.Do(func() {
511+
close(t.done)
512+
})
510513
}
511514

512515
func (t *HTTPTransport) worker() {

transport_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,28 @@ func TestHTTPTransport(t *testing.T) {
490490
wg.Wait()
491491
})
492492
}
493+
func TestHTTPTransport_CloseMultipleTimes(t *testing.T) {
494+
server := newTestHTTPServer(t)
495+
defer server.Close()
496+
transport := NewHTTPTransport()
497+
transport.Configure(ClientOptions{
498+
Dsn: fmt.Sprintf("https://test@%s/1", server.Listener.Addr()),
499+
HTTPClient: server.Client(),
500+
})
501+
502+
// Closing multiple times should not panic.
503+
for i := 0; i < 10; i++ {
504+
transport.Close()
505+
}
506+
507+
// Verify the done channel is closed
508+
select {
509+
case <-transport.done:
510+
// Expected - channel should be closed
511+
case <-time.After(time.Second):
512+
t.Fatal("transport.done not closed")
513+
}
514+
}
493515

494516
func TestHTTPTransport_FlushWithContext(t *testing.T) {
495517
server := newTestHTTPServer(t)

0 commit comments

Comments
 (0)