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 ;
20
19
import java .nio .file .attribute .PosixFilePermissions ;
21
20
import java .time .Instant ;
22
21
import java .time .temporal .ChronoUnit ;
22
+ import java .util .Map ;
23
23
import java .util .Set ;
24
+ import java .util .concurrent .ConcurrentHashMap ;
24
25
import java .util .concurrent .CountDownLatch ;
25
26
import java .util .concurrent .TimeUnit ;
26
27
import java .util .concurrent .atomic .AtomicReference ;
@@ -69,22 +70,20 @@ default FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOE
69
70
return null ;
70
71
}
71
72
72
- default void onCleanupStart (boolean selfCleanup , long timeout , TimeUnit unit ) {}
73
+ default void onCleanupStart (long timeout , TimeUnit unit ) {}
73
74
}
74
75
75
76
private final class CleanupVisitor implements FileVisitor <Path > {
76
77
private boolean shouldClean ;
77
78
78
79
private Set <String > pidSet ;
79
80
80
- private final boolean cleanSelf ;
81
81
private final Instant cutoff ;
82
82
private final Instant timeoutTarget ;
83
83
84
84
private boolean terminated = false ;
85
85
86
- CleanupVisitor (boolean cleanSelf , long timeout , TimeUnit unit ) {
87
- this .cleanSelf = cleanSelf ;
86
+ CleanupVisitor (long timeout , TimeUnit unit ) {
88
87
this .cutoff = Instant .now ().minus (cutoffSeconds , ChronoUnit .SECONDS );
89
88
this .timeoutTarget =
90
89
timeout > -1
@@ -108,10 +107,6 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
108
107
terminated = true ;
109
108
return FileVisitResult .TERMINATE ;
110
109
}
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
- }
115
110
116
111
cleanupTestHook .preVisitDirectory (dir , attrs );
117
112
@@ -122,9 +117,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
122
117
// the JFR repository directories are under <basedir>/pid_<pid>
123
118
String pid = fileName .startsWith (TEMPDIR_PREFIX ) ? fileName .substring (4 ) : null ;
124
119
boolean isSelfPid = pid != null && pid .equals (PidHelper .getPid ());
125
- if (cleanSelf ) {
126
- shouldClean |= isSelfPid ;
127
- } else if (!isSelfPid ) {
120
+ if (!isSelfPid ) {
128
121
if (pidSet == null ) {
129
122
pidSet = PidHelper .getJavaPids (); // only fork jps when required
130
123
}
@@ -202,7 +195,7 @@ private final class CleanupTask implements Runnable {
202
195
@ Override
203
196
public void run () {
204
197
try {
205
- cleanup (false );
198
+ cleanup ();
206
199
} catch (OutOfMemoryError oom ) {
207
200
throw oom ;
208
201
} catch (Throwable t ) {
@@ -229,6 +222,8 @@ boolean await(long timeout, TimeUnit unit) throws Throwable {
229
222
private final CleanupTask cleanupTask = new CleanupTask ();
230
223
private final CleanupHook cleanupTestHook ;
231
224
225
+ private final Map <Path , Path > ignoredPaths = new ConcurrentHashMap <>();
226
+
232
227
/**
233
228
* Get the singleton instance of the TempLocationManager. It will run the cleanup task in the
234
229
* background.
@@ -310,20 +305,6 @@ private TempLocationManager() {
310
305
AgentTaskScheduler .INSTANCE .execute (cleanupTask );
311
306
}
312
307
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
-
327
308
createTempDir (tempDir );
328
309
}
329
310
@@ -375,30 +356,38 @@ public Path getTempDir(Path subPath, boolean create) {
375
356
return rslt ;
376
357
}
377
358
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
+
378
371
/**
379
372
* Walk the base temp directory recursively and remove all inactive per-process entries. No
380
373
* timeout is applied.
381
374
*
382
- * @param cleanSelf {@literal true} will call only this process' temp directory, {@literal false}
383
- * only the other processes will be cleaned up
384
375
* @return {@literal true} if cleanup fully succeeded or {@literal false} otherwise (eg.
385
376
* interruption etc.)
386
377
*/
387
- boolean cleanup (boolean cleanSelf ) {
388
- return cleanup (cleanSelf , -1 , TimeUnit .SECONDS );
378
+ boolean cleanup () {
379
+ return cleanup (-1 , TimeUnit .SECONDS );
389
380
}
390
381
391
382
/**
392
383
* Walk the base temp directory recursively and remove all inactive per-process entries
393
384
*
394
- * @param cleanSelf {@literal true} will call only this process' temp directory, {@literal false}
395
- * only the other processes will be cleaned up
396
385
* @param timeout the task timeout; may be {@literal -1} to signal no timeout
397
386
* @param unit the task timeout unit
398
387
* @return {@literal true} if cleanup fully succeeded or {@literal false} otherwise (timeout,
399
388
* interruption etc.)
400
389
*/
401
- boolean cleanup (boolean cleanSelf , long timeout , TimeUnit unit ) {
390
+ boolean cleanup (long timeout , TimeUnit unit ) {
402
391
try {
403
392
if (!Files .exists (baseTempDir )) {
404
393
// not even the main temp location exists; nothing to clean up
@@ -413,8 +402,8 @@ boolean cleanup(boolean cleanSelf, long timeout, TimeUnit unit) {
413
402
return true ;
414
403
}
415
404
}
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 );
418
407
Files .walkFileTree (baseTempDir , visitor );
419
408
return !visitor .isTerminated ();
420
409
} catch (IOException e ) {
0 commit comments