Skip to content

Commit c1cbca1

Browse files
dougqhdevflow.devflow-routing-intake
andauthored
Reuse SpanKind Entry in ClientDecorator (#10503)
Updating tests to account for API changes Adding tagIterator and valueIterator Adding checks for EntryIterator Removing EntryIterator and EntryChangeIterator EntryIterator and EntryChangeIterator are arguably redundant spotless Merge branch 'master' into dougqh/tagmap-entryreader Refining handling of primitive types Fixed bug TagValueConversions.toBoolean Could cause LegacyTagMap.EntryReader to produce incorrect answers to some queries For simplicity, now treating Byte and Short as Integer. That will make calling code doing primitive handling simpler. Fleshing out tests -- more tests to come Refining comment in toBoolean Adding more TagValueConversionTest-s Coverage for byte, short, float, and double Adding Entry tests for byte and short boxes spotless Merge branch 'master' into dougqh/tagmap-entryreader Merge branch 'master' into dougqh/tagmap-entryreader Direct TagMap.Entry support in AgentSpan / DDSpan Adding methods to AgentSpan / DDSpan that take TagMap.Entry/Reader objects directly This will enable TagMap.Entry reuse which can reduce memory allocation/GC pressure Adding public create methods to TagMap.Entry Methods are intended to be used to create TagMap.Entry objects for repeatedly used values Overloads are provided for all the supported types to be easier for developers not familiar with TagMap internals. Internally, TagMap still uses the more explicit new<X>Entry methods. spotless Merge branch 'master' into dougqh/fdirect-apis-for-tagmap-entry Fixed merge Removing statics that were previously moved to TagValueConversions Clarifying comments Adding tests for TagMap.Entry.create - tests exposed missing TagMap.Entry.create for boolean - added explanatory strings to some asserts spotless Comments Merge branch 'master' into dougqh/fdirect-apis-for-tagmap-entry Adding test for TagMap.Entry setters Merge branch 'dougqh/fdirect-apis-for-tagmap-entry' of github.com:DataDog/dd-trace-java into dougqh/fdirect-apis-for-tagmap-entry Adding missing import spotless Groovy codeNarc Merge branch 'master' into dougqh/fdirect-apis-for-tagmap-entry Caching & reusing spanKind entry to reduce allocation Merge branch 'master' into dougqh/client-kind-entry-reuse Test clean-up Some of this was a bad merge, but I probably missed some in my other PR, too Merge branch 'master' into dougqh/client-kind-entry-reuse Clean-up oversights caught in review Adding explanatory comment on reason behind the approach Merge branch 'master' into dougqh/client-kind-entry-reuse Fixing the tests Merge branch 'master' into dougqh/client-kind-entry-reuse Co-authored-by: devflow.devflow-routing-intake <devflow.devflow-routing-intake@kubernetes.us1.ddbuild.io>
1 parent 8fbdc86 commit c1cbca1

5 files changed

Lines changed: 32 additions & 26 deletions

File tree

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/ClientDecorator.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,32 @@
11
package datadog.trace.bootstrap.instrumentation.decorator;
22

3+
import datadog.trace.api.TagMap;
34
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
45
import datadog.trace.bootstrap.instrumentation.api.Tags;
56

67
public abstract class ClientDecorator extends BaseDecorator {
8+
// Deliberately not volatile, reading a stale null and creating an extra Entry is safe
9+
private TagMap.Entry cachedSpanKindEntry = null;
710

811
protected abstract String service();
912

13+
/** Caches span kind entry to reduce allocation */
14+
private final TagMap.Entry spanKindEntry() {
15+
// DQH - I considered moving the creation of the TagMap.Entry into a ClientDecorator
16+
// constructor, but that introduces a subtle ordering requirement.
17+
18+
// If the spanKind method refers to a static that isn't yet initialized,
19+
// then spanKind will return null when the Decorator singleton is being constructed.
20+
21+
// Such an ordering problem did occur with similar changes in BaseDecorator, so I've
22+
// decided to be cautious here, too.
23+
TagMap.Entry kindEntry = cachedSpanKindEntry;
24+
if (kindEntry == null) {
25+
cachedSpanKindEntry = kindEntry = TagMap.Entry.create(Tags.SPAN_KIND, spanKind());
26+
}
27+
return kindEntry;
28+
}
29+
1030
protected String spanKind() {
1131
return Tags.SPAN_KIND_CLIENT;
1232
}
@@ -17,7 +37,7 @@ public AgentSpan afterStart(final AgentSpan span) {
1737
if (service != null) {
1838
span.setServiceName(service, component());
1939
}
20-
span.setTag(Tags.SPAN_KIND, spanKind());
40+
span.setTag(spanKindEntry());
2141

2242
// Generate metrics for all client spans.
2343
span.setMeasured(true);

dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/ClientDecoratorTest.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ class ClientDecoratorTest extends BaseDecoratorTest {
2626
1 * span.setTag(TagMap.Entry.create(Tags.COMPONENT, "test-component"))
2727
1 * span.context() >> spanContext
2828
1 * spanContext.setIntegrationName("test-component")
29-
1 * span.setTag(Tags.SPAN_KIND, "client")
29+
1 * span.setTag(TagMap.Entry.create(Tags.SPAN_KIND, "client"))
3030
1 * span.setSpanType(decorator.spanType())
3131
1 * span.setMetric(TagMap.Entry.create(DDTags.ANALYTICS_SAMPLE_RATE, 1.0))
3232
_ * span.setTag(_)
3333
_ * span.setTag(_, _) // Want to allow other calls from child implementations.
34+
_ * span.setTag(_)
3435
_ * span.setServiceName(_)
3536
_ * span.setOperationName(_)
3637
0 * _

dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DBTypeProcessingDatabaseClientDecoratorTest.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package datadog.trace.bootstrap.instrumentation.decorator
22

33
import datadog.trace.api.DDTags
4+
import datadog.trace.api.TagMap
45
import datadog.trace.bootstrap.instrumentation.api.AgentSpan
56
import datadog.trace.bootstrap.instrumentation.api.Tags
67
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString
@@ -26,7 +27,7 @@ class DBTypeProcessingDatabaseClientDecoratorTest extends ClientDecoratorTest {
2627
1 * span.setTag(Tags.COMPONENT, "test-component")
2728
1 * span.context() >> spanContext
2829
1 * spanContext.setIntegrationName("test-component")
29-
1 * span.setTag(Tags.SPAN_KIND, "client")
30+
1 * span.setTag(TagMap.Entry.create(Tags.SPAN_KIND, "client"))
3031
1 * span.setSpanType("test-type")
3132
1 * span.setServiceName("test-db")
3233
1 * span.setOperationName(UTF8BytesString.create("test-db.query"))

dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/DatabaseClientDecoratorTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DatabaseClientDecoratorTest extends ClientDecoratorTest {
3030
1 * span.setTag(TagMap.Entry.create(Tags.COMPONENT, "test-component"))
3131
1 * span.context() >> spanContext
3232
1 * spanContext.setIntegrationName("test-component")
33-
1 * span.setTag(Tags.SPAN_KIND, "client")
33+
1 * span.setTag(TagMap.Entry.create(Tags.SPAN_KIND, "client"))
3434
1 * span.setSpanType("test-type")
3535
1 * span.setMetric(TagMap.Entry.create(DDTags.ANALYTICS_SAMPLE_RATE, 1.0))
3636
0 * _

internal-api/src/test/java/datadog/trace/api/TagMapEntryTest.java

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public void createEmptyCharSequence() {
104104
}
105105

106106
@Test
107-
public void objectEntry() {
107+
public void newObjectEntry() {
108108
test(
109109
() -> TagMap.Entry.newObjectEntry("foo", "bar"),
110110
TagMap.Entry.OBJECT,
@@ -119,7 +119,7 @@ public void objectEntry() {
119119
}
120120

121121
@Test
122-
@DisplayName("anyEntry: Object")
122+
@DisplayName("newAnyEntry: Object")
123123
public void anyEntryObject() {
124124
test(
125125
() -> TagMap.Entry.newAnyEntry("foo", "bar"),
@@ -253,7 +253,7 @@ public void newIntEntryBoxed(int value) {
253253
@ParameterizedTest
254254
@DisplayName("newIntEntry: Short")
255255
@ValueSource(shorts = {Short.MIN_VALUE, -256, -128, -1, 0, 1, 128, 256, Short.MAX_VALUE})
256-
public void intEntryBoxedShort(short value) {
256+
public void newIntEntryBoxedShort(short value) {
257257
test(
258258
() -> TagMap.Entry.newIntEntry("foo", Short.valueOf(value)),
259259
TagMap.Entry.INT,
@@ -269,7 +269,7 @@ public void intEntryBoxedShort(short value) {
269269
@ParameterizedTest
270270
@DisplayName("newIntEntry: Byte")
271271
@ValueSource(bytes = {Byte.MIN_VALUE, -32, -1, 0, 1, 32, Byte.MAX_VALUE})
272-
public void intEntryBoxedByte(byte value) {
272+
public void newIntEntryBoxedByte(byte value) {
273273
test(
274274
() -> TagMap.Entry.newIntEntry("foo", Byte.valueOf(value)),
275275
TagMap.Entry.INT,
@@ -497,25 +497,9 @@ public void createDouble(double value) {
497497
}
498498

499499
@ParameterizedTest
500-
@DisplayName("newDoubleEntry: double")
501500
@ValueSource(
502501
doubles = {Double.MIN_VALUE, Float.MIN_VALUE, -1D, 0D, 1D, Math.E, Math.PI, Double.MAX_VALUE})
503-
public void doubleEntry_via_create(double value) {
504-
test(
505-
() -> TagMap.Entry.create("foo", value),
506-
TagMap.Entry.DOUBLE,
507-
(entry) ->
508-
multiCheck(
509-
checkKey("foo", entry),
510-
checkValue(value, entry),
511-
checkIsNumericPrimitive(entry),
512-
checkType(TagMap.Entry.DOUBLE, entry)));
513-
}
514-
515-
@ParameterizedTest
516-
@ValueSource(
517-
doubles = {Double.MIN_VALUE, Float.MIN_VALUE, -1D, 0D, 1D, Math.E, Math.PI, Double.MAX_VALUE})
518-
public void doubleEntry(double value) {
502+
public void newDoubleEntry(double value) {
519503
test(
520504
() -> TagMap.Entry.newDoubleEntry("foo", value),
521505
TagMap.Entry.DOUBLE,
@@ -547,7 +531,7 @@ public void newDoubleEntryBoxed(double value) {
547531
@DisplayName("newAnyEntry: Double")
548532
@ValueSource(
549533
doubles = {Double.MIN_VALUE, Float.MIN_VALUE, -1D, 0D, 1D, Math.E, Math.PI, Double.MAX_VALUE})
550-
public void anyEntry_double(double value) {
534+
public void newAnyEntryDouble(double value) {
551535
test(
552536
() -> TagMap.Entry.newAnyEntry("foo", Double.valueOf(value)),
553537
TagMap.Entry.ANY,

0 commit comments

Comments
 (0)