Skip to content

Commit fc0da56

Browse files
Cache TestEventsHandler instance (DataDog#5194)
1 parent 0430b67 commit fc0da56

7 files changed

Lines changed: 111 additions & 3 deletions

File tree

dd-java-agent/agent-ci-visibility/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ excludedClassesCoverage += [
2020
"datadog.trace.civisibility.context.ParentProcessTestContext",
2121
"datadog.trace.civisibility.context.SpanTestContext",
2222
"datadog.trace.civisibility.events.BuildEventsHandlerImpl",
23+
"datadog.trace.civisibility.events.CachingTestEventsHandlerFactory.CacheKey",
2324
"datadog.trace.civisibility.events.TestEventsHandlerImpl",
2425
"datadog.trace.civisibility.events.TestDescriptor",
2526
"datadog.trace.civisibility.events.TestModuleDescriptor",

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/CiVisibilitySystem.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import datadog.trace.civisibility.ci.CITagsProviderImpl;
1717
import datadog.trace.civisibility.codeowners.CodeownersProvider;
1818
import datadog.trace.civisibility.events.BuildEventsHandlerImpl;
19+
import datadog.trace.civisibility.events.CachingTestEventsHandlerFactory;
1920
import datadog.trace.civisibility.events.TestEventsHandlerImpl;
2021
import datadog.trace.civisibility.git.CILocalGitInfoBuilder;
2122
import datadog.trace.civisibility.git.CIProviderGitInfoBuilder;
@@ -36,13 +37,18 @@ public class CiVisibilitySystem {
3637
private static final String GIT_FOLDER_NAME = ".git";
3738

3839
public static void start() {
39-
if (!Config.get().isCiVisibilityEnabled()) {
40+
Config config = Config.get();
41+
if (!config.isCiVisibilityEnabled()) {
4042
LOGGER.debug("CI Visibility is disabled");
4143
return;
4244
}
4345

44-
InstrumentationBridge.registerTestEventsHandlerFactory(
45-
CiVisibilitySystem::createTestEventsHandler);
46+
TestEventsHandler.Factory factory =
47+
new CachingTestEventsHandlerFactory(
48+
CiVisibilitySystem::createTestEventsHandler,
49+
config.getCiVisibilityTestEventsHandlerCacheSize());
50+
51+
InstrumentationBridge.registerTestEventsHandlerFactory(factory);
4652
InstrumentationBridge.registerBuildEventsHandlerFactory(BuildEventsHandlerImpl::new);
4753
InstrumentationBridge.registerTestDecoratorFactory(CiVisibilitySystem::createTestDecorator);
4854

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package datadog.trace.civisibility.events;
2+
3+
import datadog.trace.api.cache.DDCache;
4+
import datadog.trace.api.cache.DDCaches;
5+
import datadog.trace.api.civisibility.events.TestEventsHandler;
6+
import java.nio.file.Path;
7+
import java.util.Objects;
8+
9+
public class CachingTestEventsHandlerFactory implements TestEventsHandler.Factory {
10+
11+
private final TestEventsHandler.Factory delegate;
12+
private final DDCache<CacheKey, TestEventsHandler> testEventsHandlerCache;
13+
14+
public CachingTestEventsHandlerFactory(TestEventsHandler.Factory delegate, int cacheSize) {
15+
this.delegate = delegate;
16+
testEventsHandlerCache = DDCaches.newFixedSizeCache(cacheSize);
17+
}
18+
19+
@Override
20+
public TestEventsHandler create(
21+
String component, String testFramework, String testFrameworkVersion, Path path) {
22+
CacheKey key = new CacheKey(component, testFramework, testFrameworkVersion, path);
23+
return testEventsHandlerCache.computeIfAbsent(
24+
key, k -> delegate.create(k.component, k.testFramework, k.testFrameworkVersion, k.path));
25+
}
26+
27+
private static final class CacheKey {
28+
private final String component;
29+
private final String testFramework;
30+
private final String testFrameworkVersion;
31+
private final Path path;
32+
33+
private CacheKey(
34+
String component, String testFramework, String testFrameworkVersion, Path path) {
35+
this.component = component;
36+
this.testFramework = testFramework;
37+
this.testFrameworkVersion = testFrameworkVersion;
38+
this.path = path;
39+
}
40+
41+
@Override
42+
public boolean equals(Object o) {
43+
if (this == o) {
44+
return true;
45+
}
46+
if (o == null || getClass() != o.getClass()) {
47+
return false;
48+
}
49+
CacheKey cacheKey = (CacheKey) o;
50+
return Objects.equals(component, cacheKey.component)
51+
&& Objects.equals(testFramework, cacheKey.testFramework)
52+
&& Objects.equals(testFrameworkVersion, cacheKey.testFrameworkVersion)
53+
&& Objects.equals(path, cacheKey.path);
54+
}
55+
56+
@Override
57+
public int hashCode() {
58+
return Objects.hash(component, testFramework, testFrameworkVersion, path);
59+
}
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package datadog.trace.civisibility.events
2+
3+
import datadog.trace.api.civisibility.events.TestEventsHandler
4+
import spock.lang.Specification
5+
6+
import java.nio.file.Paths
7+
8+
class CachingTestEventsHandlerFactoryTest extends Specification {
9+
10+
def "verify TestEventsHandler is cached"() {
11+
given:
12+
def delegate = Mock(TestEventsHandler.Factory)
13+
delegate.create("component", "framework", "version", Paths.get("path")) >> { Mock(TestEventsHandler) }
14+
15+
when:
16+
def factory = new CachingTestEventsHandlerFactory(delegate, 1)
17+
def handlerA = factory.create("component", "framework", "version", Paths.get("path"))
18+
def handlerB = factory.create("component", "framework", "version", Paths.get("path"))
19+
20+
then:
21+
handlerA == handlerB
22+
1 * delegate.create("component", "framework", "version", Paths.get("path"))
23+
0 * _
24+
}
25+
}

dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public final class ConfigDefaults {
111111
static final boolean DEFAULT_CIVISIBILITY_AUTO_CONFIGURATION_ENABLED = true;
112112
static final boolean DEFAULT_CIVISIBILITY_COMPILER_PLUGIN_AUTO_CONFIGURATION_ENABLED = true;
113113
static final String DEFAULT_CIVISIBILITY_COMPILER_PLUGIN_VERSION = "0.1.6";
114+
static final int DEFAULT_CIVISIBILITY_TEST_EVENTS_HANDLER_CACHE_SIZE = 4;
114115

115116
static final boolean DEFAULT_REMOTE_CONFIG_ENABLED = true;
116117
static final boolean DEFAULT_REMOTE_CONFIG_INTEGRITY_CHECK_ENABLED = false;

dd-trace-api/src/main/java/datadog/trace/api/config/CiVisibilityConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public final class CiVisibilityConfig {
1919
public static final String CIVISIBILITY_COMPILER_PLUGIN_VERSION =
2020
"civisibility.compiler.plugin.version";
2121
public static final String CIVISIBILITY_DEBUG_PORT = "civisibility.debug.port";
22+
public static final String CIVISIBILITY_TEST_EVENTS_HANDLER_CACHE_SIZE =
23+
"civisibility.test.events.handler.cache.size";
2224

2325
private CiVisibilityConfig() {}
2426
}

internal-api/src/main/java/datadog/trace/api/Config.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import static datadog.trace.api.ConfigDefaults.DEFAULT_CIVISIBILITY_COMPILER_PLUGIN_AUTO_CONFIGURATION_ENABLED;
1515
import static datadog.trace.api.ConfigDefaults.DEFAULT_CIVISIBILITY_COMPILER_PLUGIN_VERSION;
1616
import static datadog.trace.api.ConfigDefaults.DEFAULT_CIVISIBILITY_SOURCE_DATA_ENABLED;
17+
import static datadog.trace.api.ConfigDefaults.DEFAULT_CIVISIBILITY_TEST_EVENTS_HANDLER_CACHE_SIZE;
1718
import static datadog.trace.api.ConfigDefaults.DEFAULT_CLIENT_IP_ENABLED;
1819
import static datadog.trace.api.ConfigDefaults.DEFAULT_CLOCK_SYNC_PERIOD;
1920
import static datadog.trace.api.ConfigDefaults.DEFAULT_CWS_ENABLED;
@@ -114,6 +115,7 @@
114115
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_MODULE_ID;
115116
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_SESSION_ID;
116117
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_SOURCE_DATA_ENABLED;
118+
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_TEST_EVENTS_HANDLER_CACHE_SIZE;
117119
import static datadog.trace.api.config.CrashTrackingConfig.CRASH_TRACKING_AGENTLESS;
118120
import static datadog.trace.api.config.CrashTrackingConfig.CRASH_TRACKING_AGENTLESS_DEFAULT;
119121
import static datadog.trace.api.config.CrashTrackingConfig.CRASH_TRACKING_TAGS;
@@ -582,6 +584,7 @@ static class HostNameHolder {
582584
private final boolean ciVisibilityCompilerPluginAutoConfigurationEnabled;
583585
private final String ciVisibilityCompilerPluginVersion;
584586
private final Integer ciVisibilityDebugPort;
587+
private final int ciVisibilityTestEventsHandlerCacheSize;
585588

586589
private final boolean remoteConfigEnabled;
587590
private final boolean remoteConfigIntegrityCheckEnabled;
@@ -1328,6 +1331,11 @@ private Config(final ConfigProvider configProvider, final InstrumenterConfig ins
13281331
CIVISIBILITY_BUILD_INSTRUMENTATION_ENABLED,
13291332
DEFAULT_CIVISIBILITY_BUILD_INSTRUMENTATION_ENABLED);
13301333

1334+
ciVisibilityTestEventsHandlerCacheSize =
1335+
configProvider.getInteger(
1336+
CIVISIBILITY_TEST_EVENTS_HANDLER_CACHE_SIZE,
1337+
DEFAULT_CIVISIBILITY_TEST_EVENTS_HANDLER_CACHE_SIZE);
1338+
13311339
ciVisibilitySessionId = configProvider.getLong(CIVISIBILITY_SESSION_ID);
13321340
ciVisibilityModuleId = configProvider.getLong(CIVISIBILITY_MODULE_ID);
13331341

@@ -2166,6 +2174,10 @@ public boolean isCiVisibilityBuildInstrumentationEnabled() {
21662174
return ciVisibilityBuildInstrumentationEnabled;
21672175
}
21682176

2177+
public int getCiVisibilityTestEventsHandlerCacheSize() {
2178+
return ciVisibilityTestEventsHandlerCacheSize;
2179+
}
2180+
21692181
public Long getCiVisibilitySessionId() {
21702182
return ciVisibilitySessionId;
21712183
}

0 commit comments

Comments
 (0)