Skip to content

Commit bf97f2a

Browse files
committed
Make source file tracking asynchronous
Source file tracking is enqueueing classfile buffer to be processed by a background thread avoiding startup delay.
1 parent 2623e84 commit bf97f2a

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerAgent.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,7 @@ public static synchronized void run(Instrumentation inst, SharedCommunicationObj
7474
Config config = Config.get();
7575
DebuggerContext.initProductConfigUpdater(new DefaultProductConfigUpdater());
7676
classesToRetransformFinder = new ClassesToRetransformFinder();
77-
if (config.isDynamicInstrumentationEnabled() || config.isDebuggerExceptionEnabled()) {
78-
// only activate Source File Tracking if DI or ER is enabled from the start
79-
setupSourceFileTracking(instrumentation, classesToRetransformFinder);
80-
}
77+
//setupSourceFileTracking(instrumentation, classesToRetransformFinder);
8178
if (config.isDebuggerCodeOriginEnabled()) {
8279
startCodeOriginForSpans();
8380
}
@@ -314,7 +311,10 @@ private static String getDiagnosticEndpoint(
314311

315312
private static void setupSourceFileTracking(
316313
Instrumentation instrumentation, ClassesToRetransformFinder finder) {
317-
instrumentation.addTransformer(new SourceFileTrackingTransformer(finder));
314+
SourceFileTrackingTransformer sourceFileTrackingTransformer =
315+
new SourceFileTrackingTransformer(finder);
316+
//sourceFileTrackingTransformer.start();
317+
//instrumentation.addTransformer(sourceFileTrackingTransformer);
318318
}
319319

320320
private static void loadFromFile(

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/SourceFileTrackingTransformer.java

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,57 @@
44
import static com.datadog.debugger.util.ClassFileHelper.stripPackagePath;
55

66
import com.datadog.debugger.util.ClassFileHelper;
7+
import datadog.trace.util.AgentTaskScheduler;
78
import java.lang.instrument.ClassFileTransformer;
89
import java.lang.instrument.IllegalClassFormatException;
910
import java.security.ProtectionDomain;
11+
import java.util.Queue;
12+
import java.util.concurrent.ConcurrentLinkedQueue;
13+
import java.util.concurrent.TimeUnit;
14+
import org.slf4j.Logger;
15+
import org.slf4j.LoggerFactory;
1016

1117
/**
1218
* Permanent Transformer to track all Inner or Top-Level classes associated with the same SourceFile
1319
* (String.java) Allows to get all classes that are dependent from a source file and be able to
1420
* trigger {@link java.lang.instrument.Instrumentation#retransformClasses(Class[])} on them
1521
*/
1622
public class SourceFileTrackingTransformer implements ClassFileTransformer {
23+
private static final Logger LOGGER = LoggerFactory.getLogger(SourceFileTrackingTransformer.class);
24+
1725
private final ClassesToRetransformFinder finder;
26+
private final Queue<SourceFileItem> queue = new ConcurrentLinkedQueue<>();
27+
private final AgentTaskScheduler scheduler = AgentTaskScheduler.INSTANCE;
28+
private AgentTaskScheduler.Scheduled<Runnable> scheduled;
1829

1930
public SourceFileTrackingTransformer(ClassesToRetransformFinder finder) {
2031
this.finder = finder;
2132
}
2233

34+
public void start() {
35+
scheduled = scheduler.scheduleAtFixedRate(this::flush, 0, 1, TimeUnit.SECONDS);
36+
}
37+
38+
public void stop() {
39+
if (scheduled != null) {
40+
scheduled.cancel();
41+
}
42+
}
43+
44+
void flush() {
45+
if (queue.isEmpty()) {
46+
return;
47+
}
48+
int size = queue.size();
49+
long start = System.nanoTime();
50+
SourceFileItem item;
51+
while ((item = queue.poll()) != null) {
52+
registerSourceFile(item.className, item.classfileBuffer);
53+
}
54+
LOGGER.debug(
55+
"flushing {} source file items in {}ms", size, (System.nanoTime() - start) / 1_000_000);
56+
}
57+
2358
@Override
2459
public byte[] transform(
2560
ClassLoader loader,
@@ -31,16 +66,30 @@ public byte[] transform(
3166
if (className == null) {
3267
return null;
3368
}
69+
//queue.add(new SourceFileItem(className, classfileBuffer));
70+
return null;
71+
}
72+
73+
private void registerSourceFile(String className, byte[] classfileBuffer) {
3474
String sourceFile = ClassFileHelper.extractSourceFile(classfileBuffer);
3575
if (sourceFile == null) {
36-
return null;
76+
return;
3777
}
3878
String simpleClassName = stripPackagePath(className);
3979
String simpleSourceFile = removeExtension(sourceFile);
4080
if (simpleClassName.equals(simpleSourceFile)) {
41-
return null;
81+
return;
4282
}
4383
finder.register(sourceFile, className);
44-
return null;
84+
}
85+
86+
private static class SourceFileItem {
87+
final String className;
88+
final byte[] classfileBuffer;
89+
90+
public SourceFileItem(String className, byte[] classfileBuffer) {
91+
this.className = className;
92+
this.classfileBuffer = classfileBuffer;
93+
}
4594
}
4695
}

0 commit comments

Comments
 (0)