11package com .datadog .profiling .controller ;
22
33import static datadog .trace .api .telemetry .LogCollector .SEND_TELEMETRY ;
4- import static datadog .trace .util .AgentThreadFactory .AGENT_THREAD_GROUP ;
54
65import datadog .trace .api .config .ProfilingConfig ;
76import datadog .trace .bootstrap .config .provider .ConfigProvider ;
2019import java .nio .file .attribute .PosixFilePermissions ;
2120import java .time .Instant ;
2221import java .time .temporal .ChronoUnit ;
22+ import java .util .Map ;
2323import java .util .Set ;
24+ import java .util .concurrent .ConcurrentHashMap ;
2425import java .util .concurrent .CountDownLatch ;
2526import java .util .concurrent .TimeUnit ;
2627import java .util .concurrent .atomic .AtomicReference ;
@@ -69,22 +70,20 @@ default FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOE
6970 return null ;
7071 }
7172
72- default void onCleanupStart (boolean selfCleanup , long timeout , TimeUnit unit ) {}
73+ default void onCleanupStart (long timeout , TimeUnit unit ) {}
7374 }
7475
7576 private final class CleanupVisitor implements FileVisitor <Path > {
7677 private boolean shouldClean ;
7778
7879 private Set <String > pidSet ;
7980
80- private final boolean cleanSelf ;
8181 private final Instant cutoff ;
8282 private final Instant timeoutTarget ;
8383
8484 private boolean terminated = false ;
8585
86- CleanupVisitor (boolean cleanSelf , long timeout , TimeUnit unit ) {
87- this .cleanSelf = cleanSelf ;
86+ CleanupVisitor (long timeout , TimeUnit unit ) {
8887 this .cutoff = Instant .now ().minus (cutoffSeconds , ChronoUnit .SECONDS );
8988 this .timeoutTarget =
9089 timeout > -1
@@ -108,10 +107,6 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
108107 terminated = true ;
109108 return FileVisitResult .TERMINATE ;
110109 }
111- if (cleanSelf && JFR_DIR_PATTERN .matcher (dir .getFileName ().toString ()).matches ()) {
112- // do not delete JFR repository on 'self-cleanup' - it conflicts with the JFR's own cleanup
113- return FileVisitResult .SKIP_SUBTREE ;
114- }
115110
116111 cleanupTestHook .preVisitDirectory (dir , attrs );
117112
@@ -122,9 +117,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
122117 // the JFR repository directories are under <basedir>/pid_<pid>
123118 String pid = fileName .startsWith (TEMPDIR_PREFIX ) ? fileName .substring (4 ) : null ;
124119 boolean isSelfPid = pid != null && pid .equals (PidHelper .getPid ());
125- if (cleanSelf ) {
126- shouldClean |= isSelfPid ;
127- } else if (!isSelfPid ) {
120+ if (!isSelfPid ) {
128121 if (pidSet == null ) {
129122 pidSet = PidHelper .getJavaPids (); // only fork jps when required
130123 }
@@ -202,7 +195,7 @@ private final class CleanupTask implements Runnable {
202195 @ Override
203196 public void run () {
204197 try {
205- cleanup (false );
198+ cleanup ();
206199 } catch (OutOfMemoryError oom ) {
207200 throw oom ;
208201 } catch (Throwable t ) {
@@ -229,6 +222,8 @@ boolean await(long timeout, TimeUnit unit) throws Throwable {
229222 private final CleanupTask cleanupTask = new CleanupTask ();
230223 private final CleanupHook cleanupTestHook ;
231224
225+ private final Map <Path , Path > ignoredPaths = new ConcurrentHashMap <>();
226+
232227 /**
233228 * Get the singleton instance of the TempLocationManager. It will run the cleanup task in the
234229 * background.
@@ -310,20 +305,6 @@ private TempLocationManager() {
310305 AgentTaskScheduler .INSTANCE .execute (cleanupTask );
311306 }
312307
313- Thread selfCleanup =
314- new Thread (
315- AGENT_THREAD_GROUP ,
316- () -> {
317- if (!waitForCleanup (1 , TimeUnit .SECONDS )) {
318- log .info (
319- "Cleanup task timed out. {} temp directory might not have been cleaned up properly" ,
320- tempDir );
321- }
322- cleanup (true );
323- },
324- "Temp Location Manager Cleanup" );
325- Runtime .getRuntime ().addShutdownHook (selfCleanup );
326-
327308 createTempDir (tempDir );
328309 }
329310
@@ -375,30 +356,38 @@ public Path getTempDir(Path subPath, boolean create) {
375356 return rslt ;
376357 }
377358
359+ public void ignore (Path path ) {
360+ if (path .startsWith (baseTempDir )) {
361+ // ignore the path if it is a child of the base temp directory
362+ ignoredPaths .put (path , path );
363+ } else {
364+ log .debug (
365+ "Path {} which is not a child of the base temp directory {} can not be ignored" ,
366+ path ,
367+ baseTempDir );
368+ }
369+ }
370+
378371 /**
379372 * Walk the base temp directory recursively and remove all inactive per-process entries. No
380373 * timeout is applied.
381374 *
382- * @param cleanSelf {@literal true} will call only this process' temp directory, {@literal false}
383- * only the other processes will be cleaned up
384375 * @return {@literal true} if cleanup fully succeeded or {@literal false} otherwise (eg.
385376 * interruption etc.)
386377 */
387- boolean cleanup (boolean cleanSelf ) {
388- return cleanup (cleanSelf , -1 , TimeUnit .SECONDS );
378+ boolean cleanup () {
379+ return cleanup (-1 , TimeUnit .SECONDS );
389380 }
390381
391382 /**
392383 * Walk the base temp directory recursively and remove all inactive per-process entries
393384 *
394- * @param cleanSelf {@literal true} will call only this process' temp directory, {@literal false}
395- * only the other processes will be cleaned up
396385 * @param timeout the task timeout; may be {@literal -1} to signal no timeout
397386 * @param unit the task timeout unit
398387 * @return {@literal true} if cleanup fully succeeded or {@literal false} otherwise (timeout,
399388 * interruption etc.)
400389 */
401- boolean cleanup (boolean cleanSelf , long timeout , TimeUnit unit ) {
390+ boolean cleanup (long timeout , TimeUnit unit ) {
402391 try {
403392 if (!Files .exists (baseTempDir )) {
404393 // not even the main temp location exists; nothing to clean up
@@ -413,8 +402,8 @@ boolean cleanup(boolean cleanSelf, long timeout, TimeUnit unit) {
413402 return true ;
414403 }
415404 }
416- cleanupTestHook .onCleanupStart (cleanSelf , timeout , unit );
417- CleanupVisitor visitor = new CleanupVisitor (cleanSelf , timeout , unit );
405+ cleanupTestHook .onCleanupStart (timeout , unit );
406+ CleanupVisitor visitor = new CleanupVisitor (timeout , unit );
418407 Files .walkFileTree (baseTempDir , visitor );
419408 return !visitor .isTerminated ();
420409 } catch (IOException e ) {
0 commit comments