Skip to content

Commit 6e98a97

Browse files
committed
Do not run the cleanup if there is nothing to clean up
(cherry picked from commit 58d5da8)
1 parent 02d8d51 commit 6e98a97

File tree

2 files changed

+75
-15
lines changed

2 files changed

+75
-15
lines changed

dd-java-agent/agent-profiling/profiling-controller/src/main/java/com/datadog/profiling/controller/TempLocationManager.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Set;
1919
import java.util.concurrent.CountDownLatch;
2020
import java.util.concurrent.TimeUnit;
21+
import java.util.stream.Stream;
2122
import org.slf4j.Logger;
2223
import org.slf4j.LoggerFactory;
2324

@@ -29,6 +30,8 @@
2930
*/
3031
public final class TempLocationManager {
3132
private static final Logger log = LoggerFactory.getLogger(TempLocationManager.class);
33+
// accessible to tests
34+
static final String TEMPDIR_PREFIX = "pid_";
3235

3336
private static final class SingletonHolder {
3437
private static final TempLocationManager INSTANCE = new TempLocationManager();
@@ -104,7 +107,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
104107
}
105108
String fileName = dir.getFileName().toString();
106109
// the JFR repository directories are under <basedir>/pid_<pid>
107-
String pid = fileName.startsWith("pid_") ? fileName.substring(4) : null;
110+
String pid = fileName.startsWith(TEMPDIR_PREFIX) ? fileName.substring(4) : null;
108111
boolean isSelfPid = pid != null && pid.equals(PidHelper.getPid());
109112
shouldClean |= cleanSelf ? isSelfPid : !isSelfPid && !pidSet.contains(pid);
110113
if (shouldClean) {
@@ -166,7 +169,7 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx
166169
}
167170
String fileName = dir.getFileName().toString();
168171
// reset the flag only if we are done cleaning the top-level directory
169-
shouldClean = !fileName.startsWith("pid_");
172+
shouldClean = !fileName.startsWith(TEMPDIR_PREFIX);
170173
}
171174
return FileVisitResult.CONTINUE;
172175
}
@@ -234,10 +237,11 @@ private TempLocationManager() {
234237
}
235238

236239
TempLocationManager(ConfigProvider configProvider) {
237-
this(configProvider, CleanupHook.EMPTY);
240+
this(configProvider, true, CleanupHook.EMPTY);
238241
}
239242

240-
TempLocationManager(ConfigProvider configProvider, CleanupHook testHook) {
243+
TempLocationManager(
244+
ConfigProvider configProvider, boolean runStartupCleanup, CleanupHook testHook) {
241245
cleanupTestHook = testHook;
242246

243247
// In order to avoid racy attempts to clean up files which are currently being processed in a
@@ -275,8 +279,11 @@ private TempLocationManager() {
275279
baseTempDir = configuredTempDir.resolve("ddprof");
276280
baseTempDir.toFile().deleteOnExit();
277281

278-
tempDir = baseTempDir.resolve("pid_" + pid);
279-
AgentTaskScheduler.INSTANCE.execute(() -> cleanup(false));
282+
tempDir = baseTempDir.resolve(TEMPDIR_PREFIX + pid);
283+
if (runStartupCleanup) {
284+
// do not execute the background cleanup task when running in tests
285+
AgentTaskScheduler.INSTANCE.execute(() -> cleanup(false));
286+
}
280287

281288
Thread selfCleanup =
282289
new Thread(
@@ -361,6 +368,19 @@ boolean cleanup(boolean cleanSelf) {
361368
*/
362369
boolean cleanup(boolean cleanSelf, long timeout, TimeUnit unit) {
363370
try {
371+
if (!Files.exists(baseTempDir)) {
372+
// not event the main temp location exists; nothing to clean up
373+
return true;
374+
}
375+
try (Stream<Path> paths = Files.walk(baseTempDir)) {
376+
if (paths.noneMatch(
377+
path ->
378+
Files.isDirectory(path)
379+
&& path.getFileName().toString().startsWith(TEMPDIR_PREFIX))) {
380+
// nothing to clean up; bail out early
381+
return true;
382+
}
383+
}
364384
cleanupTestHook.onCleanupStart(cleanSelf, timeout, unit);
365385
CleanupVisitor visitor = new CleanupVisitor(cleanSelf, timeout, unit);
366386
Files.walkFileTree(baseTempDir, visitor);
@@ -391,4 +411,9 @@ boolean waitForCleanup(long timeout, TimeUnit unit) {
391411
}
392412
return false;
393413
}
414+
415+
// accessible for tests
416+
void createDirStructure() throws IOException {
417+
Files.createDirectories(baseTempDir);
418+
}
394419
}

dd-java-agent/agent-profiling/profiling-controller/src/test/java/com/datadog/profiling/controller/TempLocationManagerTest.java

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.UUID;
1919
import java.util.concurrent.Phaser;
2020
import java.util.concurrent.TimeUnit;
21+
import java.util.concurrent.atomic.AtomicBoolean;
2122
import java.util.concurrent.locks.LockSupport;
2223
import java.util.stream.Stream;
2324
import org.junit.jupiter.api.Test;
@@ -173,7 +174,7 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx
173174
}
174175
};
175176

176-
TempLocationManager mgr = instance(baseDir, blocker);
177+
TempLocationManager mgr = instance(baseDir, true, blocker);
177178

178179
// wait for the cleanup start
179180
phaser.arriveAndAwaitAdvance();
@@ -187,8 +188,9 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx
187188

188189
@ParameterizedTest
189190
@MethodSource("timeoutTestArguments")
190-
void testCleanupWithTimeout(boolean selfCleanup, String section) throws Exception {
191-
long timeoutMs = 500;
191+
void testCleanupWithTimeout(boolean selfCleanup, boolean shouldSucceed, String section)
192+
throws Exception {
193+
long timeoutMs = 10;
192194
TempLocationManager.CleanupHook delayer =
193195
new TempLocationManager.CleanupHook() {
194196
@Override
@@ -229,30 +231,63 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
229231
Files.createTempDirectory(
230232
"ddprof-test-",
231233
PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------")));
232-
TempLocationManager instance = instance(baseDir, delayer);
233-
boolean rslt = instance.cleanup(selfCleanup, timeoutMs, TimeUnit.MILLISECONDS);
234-
assertTrue(rslt);
234+
TempLocationManager instance = instance(baseDir, false, delayer);
235+
Path mytempdir = instance.getTempDir();
236+
Path otherTempdir = mytempdir.getParent().resolve("pid_0000");
237+
Files.createDirectories(otherTempdir);
238+
Files.createFile(mytempdir.resolve("dummy"));
239+
Files.createFile(otherTempdir.resolve("dummy"));
240+
boolean rslt =
241+
instance.cleanup(
242+
selfCleanup, (long) (timeoutMs * (shouldSucceed ? 10 : 0.5d)), TimeUnit.MILLISECONDS);
243+
assertEquals(shouldSucceed, rslt);
244+
}
245+
246+
@Test
247+
void testShortCircuit() throws Exception {
248+
Path baseDir =
249+
Files.createTempDirectory(
250+
"ddprof-test-",
251+
PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------")));
252+
AtomicBoolean executed = new AtomicBoolean();
253+
TempLocationManager.CleanupHook hook =
254+
new TempLocationManager.CleanupHook() {
255+
@Override
256+
public void onCleanupStart(boolean selfCleanup, long timeout, TimeUnit unit) {
257+
executed.set(true);
258+
}
259+
};
260+
TempLocationManager instance = instance(baseDir, false, hook);
261+
262+
instance.createDirStructure();
263+
264+
boolean ret = instance.cleanup(false);
265+
assertTrue(ret);
266+
assertFalse(executed.get());
235267
}
236268

237269
private static Stream<Arguments> timeoutTestArguments() {
238270
List<Arguments> argumentsList = new ArrayList<>();
239271
for (boolean selfCleanup : new boolean[] {true, false}) {
240272
for (String intercepted :
241273
new String[] {"preVisitDirectory", "visitFile", "postVisitDirectory"}) {
242-
argumentsList.add(Arguments.of(selfCleanup, intercepted));
274+
argumentsList.add(Arguments.of(selfCleanup, true, intercepted));
275+
argumentsList.add(Arguments.of(selfCleanup, false, intercepted));
243276
}
244277
}
245278
return argumentsList.stream();
246279
}
247280

248-
private TempLocationManager instance(Path baseDir, TempLocationManager.CleanupHook cleanupHook)
281+
private TempLocationManager instance(
282+
Path baseDir, boolean withStartupCleanup, TempLocationManager.CleanupHook cleanupHook)
249283
throws IOException {
250284
Properties props = new Properties();
251285
props.put(ProfilingConfig.PROFILING_TEMP_DIR, baseDir.toString());
252286
props.put(
253287
ProfilingConfig.PROFILING_UPLOAD_PERIOD,
254288
"0"); // to force immediate cleanup; must be a string value!
255289

256-
return new TempLocationManager(ConfigProvider.withPropertiesOverride(props), cleanupHook);
290+
return new TempLocationManager(
291+
ConfigProvider.withPropertiesOverride(props), withStartupCleanup, cleanupHook);
257292
}
258293
}

0 commit comments

Comments
 (0)