Skip to content

Commit

Permalink
Merge pull request #39 from honeycombio/tredman.async_span_race
Browse files Browse the repository at this point in the history
[trace] Fix race between CreateAsyncChild and span.Send
  • Loading branch information
tredman authored Nov 28, 2018
2 parents 87bb646 + f5f2674 commit 4d5b2a2
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions trace/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,24 +270,13 @@ func (s *Span) GetParent() *Span {
// outlive the current span (and trace). Async spans are not automatically sent
// when their parent finishes, but are otherwise identical to synchronous spans.
func (s *Span) CreateAsyncChild(ctx context.Context) (context.Context, *Span) {
ctx, newSpan := s.CreateChild(ctx)
newSpan.isAsync = true
return ctx, newSpan
return s.createChildSpan(ctx, true)
}

// Span creates a synchronous child of the current span. Spans must finish
// before their parents.
func (s *Span) CreateChild(ctx context.Context) (context.Context, *Span) {
newSpan := newSpan()
newSpan.parent = s
newSpan.parentID = s.spanID
newSpan.trace = s.trace
newSpan.ev = s.trace.builder.NewEvent()
s.childrenLock.Lock()
s.children = append(s.children, newSpan)
s.childrenLock.Unlock()
ctx = PutSpanInContext(ctx, newSpan)
return ctx, newSpan
return s.createChildSpan(ctx, false)
}

// SerializeHeaders returns the trace ID, current span ID as parent ID, and an
Expand Down Expand Up @@ -370,3 +359,17 @@ func (s *Span) send() {
s.ev.SendPresampled()
}
}

func (s *Span) createChildSpan(ctx context.Context, async bool) (context.Context, *Span) {
newSpan := newSpan()
newSpan.parent = s
newSpan.parentID = s.spanID
newSpan.trace = s.trace
newSpan.ev = s.trace.builder.NewEvent()
newSpan.isAsync = async
s.childrenLock.Lock()
s.children = append(s.children, newSpan)
s.childrenLock.Unlock()
ctx = PutSpanInContext(ctx, newSpan)
return ctx, newSpan
}

0 comments on commit 4d5b2a2

Please sign in to comment.