@@ -377,20 +377,35 @@ class TestHttpServer implements AutoCloseable {
377
377
}
378
378
379
379
void handleDistributedRequest () {
380
+ final String DD_SPAN_ATTRIBUTE = " datadog.span"
381
+
380
382
boolean isDDServer = true
381
383
if (request. getHeader(" is-dd-server" ) != null ) {
382
384
isDDServer = Boolean . parseBoolean(request. getHeader(" is-dd-server" ))
383
385
}
384
386
if (isDDServer) {
385
- final AgentSpanContext extractedContext = extractContextAndGetSpanContext(req. orig, GETTER )
386
- if (extractedContext != null ) {
387
- startSpan(" test" , " test-http-server" , extractedContext)
388
- .setTag(" path" , request. path)
389
- .setTag(Tags . SPAN_KIND , Tags . SPAN_KIND_SERVER ). finish()
390
- } else {
391
- startSpan(" test" , " test-http-server" )
392
- .setTag(" path" , request. path)
393
- .setTag(Tags . SPAN_KIND , Tags . SPAN_KIND_SERVER ). finish()
387
+ // Synchronize on the request to make check-and-set atomic across threads
388
+ synchronized (req. orig) {
389
+ // Check if span already exists for this request to prevent duplicates
390
+ Object existingSpan = req. orig. getAttribute(DD_SPAN_ATTRIBUTE )
391
+ if (existingSpan != null ) {
392
+ // Span already created by another thread, skip creating duplicate
393
+ return
394
+ }
395
+
396
+ final AgentSpanContext extractedContext = extractContextAndGetSpanContext(req. orig, GETTER )
397
+ def span
398
+ if (extractedContext != null ) {
399
+ span = startSpan(" test" , " test-http-server" , extractedContext)
400
+ } else {
401
+ span = startSpan(" test" , " test-http-server" )
402
+ }
403
+ span. setTag(" path" , request. path)
404
+ .setTag(Tags . SPAN_KIND , Tags . SPAN_KIND_SERVER )
405
+ .finish()
406
+
407
+ // Store span in request attribute before finishing to prevent race conditions
408
+ req. orig. setAttribute(DD_SPAN_ATTRIBUTE , span)
394
409
}
395
410
}
396
411
}
0 commit comments