Skip to content

Commit 9fb8f43

Browse files
dougqhamarziali
authored andcommitted
Reduce PendingTrace Lock Contention (#9932)
* Attempting to reduce contention for virtual threads * spotless
1 parent 91f5e74 commit 9fb8f43

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

dd-trace-core/src/main/java/datadog/trace/core/PendingTrace.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ PublishState onPublish(final DDSpan span) {
234234
if (span == rootSpan) {
235235
tracer.onRootSpanPublished(rootSpan);
236236
}
237-
return decrementRefAndMaybeWrite(span == rootSpan);
237+
return decrementRefAndMaybeWrite(span == rootSpan, true);
238238
}
239239

240240
@Override
@@ -265,10 +265,10 @@ public void registerContinuation(final AgentScope.Continuation continuation) {
265265

266266
@Override
267267
public void removeContinuation(final AgentScope.Continuation continuation) {
268-
decrementRefAndMaybeWrite(false);
268+
decrementRefAndMaybeWrite(false, false);
269269
}
270270

271-
private PublishState decrementRefAndMaybeWrite(boolean isRootSpan) {
271+
private PublishState decrementRefAndMaybeWrite(boolean isRootSpan, boolean addedSpan) {
272272
final int count = PENDING_REFERENCE_COUNT.decrementAndGet(this);
273273
if (strictTraceWrites && count < 0) {
274274
throw new IllegalStateException("Pending reference count " + count + " is negative");
@@ -283,8 +283,19 @@ private PublishState decrementRefAndMaybeWrite(boolean isRootSpan) {
283283
// Finished root with pending work ... delay write
284284
pendingTraceBuffer.enqueue(this);
285285
return PublishState.ROOT_BUFFERED;
286-
} else if (partialFlushMinSpans > 0 && size() >= partialFlushMinSpans) {
286+
} else if (addedSpan && partialFlushMinSpans > 0 && size() >= partialFlushMinSpans) {
287287
// Trace is getting too big, write anything completed.
288+
289+
// DQH - We only trigger a partial flush, when a span has just been added
290+
// This prevents a bunch of threads which are only performing scope/context operations
291+
// from all fighting to perform the partialFlush after the threshold is crossed.
292+
293+
// This is an important optimization for virtual threads where a continuation might
294+
// be created even though no span is created. In that situation, virtual threads
295+
// can end up fighting to perform the partialFlush. And even trying to perform a
296+
// partialFlush requires taking the PendingTrace lock which can lead to unmounting
297+
// the virtual thread from its carrier thread.
298+
288299
partialFlush();
289300
return PublishState.PARTIAL_FLUSH;
290301
} else if (rootSpanWritten) {

0 commit comments

Comments
 (0)