1
1
package com .datadog .profiling .controller ;
2
2
3
3
import static datadog .trace .api .telemetry .LogCollector .SEND_TELEMETRY ;
4
- import static datadog .trace .util .AgentThreadFactory .AGENT_THREAD_GROUP ;
5
4
6
5
import datadog .trace .api .config .ProfilingConfig ;
7
6
import datadog .trace .bootstrap .config .provider .ConfigProvider ;
19
18
import java .nio .file .attribute .PosixFilePermissions ;
20
19
import java .time .Instant ;
21
20
import java .time .temporal .ChronoUnit ;
21
+ import java .util .Map ;
22
22
import java .util .Set ;
23
+ import java .util .concurrent .ConcurrentHashMap ;
23
24
import java .util .concurrent .CountDownLatch ;
24
25
import java .util .concurrent .TimeUnit ;
25
26
import java .util .regex .Pattern ;
@@ -67,22 +68,20 @@ default FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOE
67
68
return null ;
68
69
}
69
70
70
- default void onCleanupStart (boolean selfCleanup , long timeout , TimeUnit unit ) {}
71
+ default void onCleanupStart (long timeout , TimeUnit unit ) {}
71
72
}
72
73
73
74
private final class CleanupVisitor implements FileVisitor <Path > {
74
75
private boolean shouldClean ;
75
76
76
77
private Set <String > pidSet ;
77
78
78
- private final boolean cleanSelf ;
79
79
private final Instant cutoff ;
80
80
private final Instant timeoutTarget ;
81
81
82
82
private boolean terminated = false ;
83
83
84
- CleanupVisitor (boolean cleanSelf , long timeout , TimeUnit unit ) {
85
- this .cleanSelf = cleanSelf ;
84
+ CleanupVisitor (long timeout , TimeUnit unit ) {
86
85
this .cutoff = Instant .now ().minus (cutoffSeconds , ChronoUnit .SECONDS );
87
86
this .timeoutTarget =
88
87
timeout > -1
@@ -106,10 +105,6 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
106
105
terminated = true ;
107
106
return FileVisitResult .TERMINATE ;
108
107
}
109
- if (cleanSelf && JFR_DIR_PATTERN .matcher (dir .getFileName ().toString ()).matches ()) {
110
- // do not delete JFR repository on 'self-cleanup' - it conflicts with the JFR's own cleanup
111
- return FileVisitResult .SKIP_SUBTREE ;
112
- }
113
108
114
109
cleanupTestHook .preVisitDirectory (dir , attrs );
115
110
@@ -120,9 +115,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
120
115
// the JFR repository directories are under <basedir>/pid_<pid>
121
116
String pid = fileName .startsWith (TEMPDIR_PREFIX ) ? fileName .substring (4 ) : null ;
122
117
boolean isSelfPid = pid != null && pid .equals (PidHelper .getPid ());
123
- if (cleanSelf ) {
124
- shouldClean |= isSelfPid ;
125
- } else if (!isSelfPid ) {
118
+ if (!isSelfPid ) {
126
119
if (pidSet == null ) {
127
120
pidSet = PidHelper .getJavaPids (); // only fork jps when required
128
121
}
@@ -200,7 +193,7 @@ private final class CleanupTask implements Runnable {
200
193
@ Override
201
194
public void run () {
202
195
try {
203
- cleanup (false );
196
+ cleanup ();
204
197
} catch (OutOfMemoryError oom ) {
205
198
throw oom ;
206
199
} catch (Throwable t ) {
@@ -226,6 +219,8 @@ boolean await(long timeout, TimeUnit unit) throws Throwable {
226
219
private final CleanupTask cleanupTask = new CleanupTask ();
227
220
private final CleanupHook cleanupTestHook ;
228
221
222
+ private final Map <Path , Path > ignoredPaths = new ConcurrentHashMap <>();
223
+
229
224
/**
230
225
* Get the singleton instance of the TempLocationManager. It will run the cleanup task in the
231
226
* background.
@@ -303,20 +298,6 @@ private TempLocationManager() {
303
298
// do not execute the background cleanup task when running in tests
304
299
AgentTaskScheduler .INSTANCE .execute (cleanupTask );
305
300
}
306
-
307
- Thread selfCleanup =
308
- new Thread (
309
- AGENT_THREAD_GROUP ,
310
- () -> {
311
- if (!waitForCleanup (1 , TimeUnit .SECONDS )) {
312
- log .info (
313
- "Cleanup task timed out. {} temp directory might not have been cleaned up properly" ,
314
- tempDir );
315
- }
316
- cleanup (true );
317
- },
318
- "Temp Location Manager Cleanup" );
319
- Runtime .getRuntime ().addShutdownHook (selfCleanup );
320
301
}
321
302
322
303
// @VisibleForTesting
@@ -381,30 +362,38 @@ public Path getTempDir(Path subPath, boolean create) {
381
362
return rslt ;
382
363
}
383
364
365
+ public void ignore (Path path ) {
366
+ if (path .startsWith (baseTempDir )) {
367
+ // ignore the path if it is a child of the base temp directory
368
+ ignoredPaths .put (path , path );
369
+ } else {
370
+ log .debug (
371
+ "Path {} which is not a child of the base temp directory {} can not be ignored" ,
372
+ path ,
373
+ baseTempDir );
374
+ }
375
+ }
376
+
384
377
/**
385
378
* Walk the base temp directory recursively and remove all inactive per-process entries. No
386
379
* timeout is applied.
387
380
*
388
- * @param cleanSelf {@literal true} will call only this process' temp directory, {@literal false}
389
- * only the other processes will be cleaned up
390
381
* @return {@literal true} if cleanup fully succeeded or {@literal false} otherwise (eg.
391
382
* interruption etc.)
392
383
*/
393
- boolean cleanup (boolean cleanSelf ) {
394
- return cleanup (cleanSelf , -1 , TimeUnit .SECONDS );
384
+ boolean cleanup () {
385
+ return cleanup (-1 , TimeUnit .SECONDS );
395
386
}
396
387
397
388
/**
398
389
* Walk the base temp directory recursively and remove all inactive per-process entries
399
390
*
400
- * @param cleanSelf {@literal true} will call only this process' temp directory, {@literal false}
401
- * only the other processes will be cleaned up
402
391
* @param timeout the task timeout; may be {@literal -1} to signal no timeout
403
392
* @param unit the task timeout unit
404
393
* @return {@literal true} if cleanup fully succeeded or {@literal false} otherwise (timeout,
405
394
* interruption etc.)
406
395
*/
407
- boolean cleanup (boolean cleanSelf , long timeout , TimeUnit unit ) {
396
+ boolean cleanup (long timeout , TimeUnit unit ) {
408
397
try {
409
398
if (!Files .exists (baseTempDir )) {
410
399
// not even the main temp location exists; nothing to clean up
@@ -419,8 +408,8 @@ boolean cleanup(boolean cleanSelf, long timeout, TimeUnit unit) {
419
408
return true ;
420
409
}
421
410
}
422
- cleanupTestHook .onCleanupStart (cleanSelf , timeout , unit );
423
- CleanupVisitor visitor = new CleanupVisitor (cleanSelf , timeout , unit );
411
+ cleanupTestHook .onCleanupStart (timeout , unit );
412
+ CleanupVisitor visitor = new CleanupVisitor (timeout , unit );
424
413
Files .walkFileTree (baseTempDir , visitor );
425
414
return !visitor .isTerminated ();
426
415
} catch (IOException e ) {
0 commit comments