Skip to content

Commit

Permalink
Merge branch 'christian/traceidmismatch'
Browse files Browse the repository at this point in the history
  • Loading branch information
ufoot committed May 24, 2017
2 parents c6cc953 + 5bdd1a9 commit 28e7840
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 2 deletions.
20 changes: 18 additions & 2 deletions lib/ddtrace/tracer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,24 @@ def record(span)
@buffer.set(parent)

return unless parent.nil?
spans = @spans
@spans = []

# In general, all spans within the buffer belong to the same trace.
# But in heavily multithreaded contexts and/or when using lots of callbacks
# hooks and other non-linear programming style, one can technically
# end up in different situations. So we only extract the spans which
# are associated to the root span that just finished, and save the
# others for later.
trace_spans = []
alien_spans = []
@spans.each do |s|
if s.trace_id == span.trace_id
trace_spans << s
else
alien_spans << s
end
end
spans = trace_spans
@spans = alien_spans
end

return if spans.empty? || !span.sampled
Expand Down
50 changes: 50 additions & 0 deletions test/concurrent_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'helper'
require 'ddtrace/tracer'

class ConcurrentTest < Minitest::Test
def traced_task
@tracer.trace('a-root-task') do |_root_span|
delay = rand()
@tracer.trace('a-sub-task') do |sub_span|
sub_span.set_tag('delay', delay)
end
# the delay *must* be between the instant the sub-span finishes
# and the instant the root span is done.
sleep delay
end
@tracer.writer.spans()
end

def test_parallel_tasks
@tracer = get_test_tracer

semaphore = Mutex.new
threads = []
traces = []

3.times do |_i|
100.times do
thr = Thread.new do
trace = traced_task
semaphore.synchronize do
traces << trace
end
end
threads << thr
end
threads.each(&:join)
end

assert_equal(300, traces.length)
traces.each do |trace|
assert_equal(2, trace.length)
sub = trace[0]
root = trace[1]
assert_equal('a-root-task', root.name)
assert_equal('a-sub-task', sub.name)
assert_equal(root.trace_id, root.span_id)
assert_equal(root.trace_id, sub.trace_id, 'root span and sub span must have the same trace id')
assert_equal(root.trace_id, sub.parent_id)
end
end
end

0 comments on commit 28e7840

Please sign in to comment.