Skip to content

Conversation

@marcotc
Copy link
Member

@marcotc marcotc commented Oct 4, 2025

What does this PR do?

Fixes an unintended behavior of Datadog::Tracing.continue_from!(digest, &block) where if multiple local root spans are created inside a the block, only the first one is associated with the digest. Any subsequence spans inside that block are associated with a new, unrelated trace.

Effectively, this PR makes this block do what it looks like it does:

# Capture TraceDigest
digest = Datadog::Tracing.active_trace.to_digest

# Then in another thread
Datadog::Tracing.continue_trace!(digest) do
  tracer.trace('first.span') {} # Both spans are associated
  tracer.trace('second.span') {} # with the digest
end

Before this PR, only the first.span would be associated with the digest.

Motivation:

While trying to address #3465, I wasn't able to get all background spans to be associated with the active span in the main calling thread. This was due to the bug that this PR fixes.

Change log entry

Yes. Tracing.continue_from! with a block maintains active trace until the block ends.

@marcotc marcotc requested review from a team as code owners October 4, 2025 01:14
@marcotc marcotc requested a review from vpellan October 4, 2025 01:14
@github-actions
Copy link

github-actions bot commented Oct 4, 2025

Thank you for updating Change log entry section 👏

Visited at: 2025-10-04 02:07:44 UTC

@marcotc marcotc force-pushed the fix-trace-auto-finish branch from 91fa0bb to eb4376a Compare October 4, 2025 01:26
@pr-commenter
Copy link

pr-commenter bot commented Oct 4, 2025

Benchmarks

Benchmark execution time: 2025-12-08 17:55:39

Comparing candidate commit 0524bd4 in PR branch fix-trace-auto-finish with baseline commit 48b4d79 in branch master.

Found 1 performance improvements and 0 performance regressions! Performance is the same for 43 metrics, 2 unstable metrics.

scenario:profiling - stack collector (ruby frames - native filenames enabled)

  • 🟩 throughput [+207.147op/s; +209.317op/s] or [+6.636%; +6.705%]

@datadog-official
Copy link

datadog-official bot commented Oct 4, 2025

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage
Patch Coverage: 100.00%
Total Coverage: 95.23% (-0.00%)

View detailed report

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 0524bd4 | Docs | Datadog PR Page | Was this helpful? Give us feedback!

Copy link
Contributor

@maycmlee maycmlee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing for docs to review

Copy link
Member

@p-datadog p-datadog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this branch is missing #4925, if so it should have master merged into it and formatters rerun.

Copy link
Member

@Strech Strech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍🏼

P.S I've left few non-blocking suggestions

Comment on lines +286 to +299
if block
# When a block is given, the trace will be active until the block finishes.
context.activate!(trace) do
yield
ensure # We have to flush even when an error occurs
# On block completion, force the trace to finish and flush its finished spans.
# Unfinished spans are lost as the {TraceOperation} has ended.
trace.finish!
flush_trace(trace)
end
else
# Otherwise, the trace will be bound to the current thread after this point
context.activate!(trace)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be streamlined with a guard-clause

Suggested change
if block
# When a block is given, the trace will be active until the block finishes.
context.activate!(trace) do
yield
ensure # We have to flush even when an error occurs
# On block completion, force the trace to finish and flush its finished spans.
# Unfinished spans are lost as the {TraceOperation} has ended.
trace.finish!
flush_trace(trace)
end
else
# Otherwise, the trace will be bound to the current thread after this point
context.activate!(trace)
end
# The trace will be bound to the current thread if no block is given
return context.activate!(trace) unless block
# When a block is given, the trace will be active until the block finishes.
context.activate!(trace) do
yield
ensure # We have to flush even when an error occurs
# On block completion, force the trace to finish and flush its finished spans.
# Unfinished spans are lost as the {TraceOperation} has ended.
trace.finish!
flush_trace(trace)
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually prefer the current version in the PR because the proposed revision adds several negations.

# Don't finish the span, so finished_span_count remains 0
end

# No spans should be flushed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think comment is unnecessary

Suggested change
# No spans should be flushed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's there for emphasis?

@ivoanjo
Copy link
Member

ivoanjo commented Nov 27, 2025

Hey, should we go ahead and merge this one?

@p-datadog p-datadog requested a review from a team as a code owner December 8, 2025 17:19
p and others added 4 commits December 8, 2025 12:22
* master: (523 commits)
  DI: relax upper bound for reported long method duration (#5113)
  Change development guide to use Ruby 3.4 by default (#5112)
  Fix exception in RC on OpenFeature::Engine absence
  [🤖] Update Latest Dependency: https://github.com/DataDog/dd-trace-rb/actions/runs/19996135509
  [🤖] Update System Tests: https://github.com/DataDog/dd-trace-rb/actions/runs/19996155319
  Add ruby guikld to all dsm files
  add DSM to codeowners
  feat: add process tags to traces (#5033)
  DEBUG-3558 DI: chunk snapshot payloads (#5086)
  CI: enable push_to_test_optimization unless this is a pull request from a fork
  fix steep checks
  [🤖] Lock Dependency: https://github.com/DataDog/dd-trace-rb/actions/runs/19827679824
  [🤖] Lock Dependency: https://github.com/DataDog/dd-trace-rb/actions/runs/19827296218
  Add test to verify consumer backlog serialization with kafka_commit tag
  Remove one diagnostic output
  Install rubygems
  Add diagnostic steps
  Use default rubygems+bundler for each Ruby version
  Revert "Disable profiling specs for 4.0"
  Use git `datadog-ruby_core_source` having 4.0
  ...
@p-datadog
Copy link
Member

I will be clicking the merge button on this after the release is complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants