Skip to content

Commit d4edff9

Browse files
authored
fix(temp-files): prevent cleanup of active registered directories (Stirling-Tools#7006)
1 parent 80febc9 commit d4edff9

4 files changed

Lines changed: 50 additions & 2 deletions

File tree

app/common/src/main/java/stirling/software/common/service/TempFileCleanupService.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,10 @@ public void scheduledCleanup() {
144144
int directoriesDeletedCount = 0;
145145
for (Path directory : registry.getTempDirectories()) {
146146
try {
147-
if (Files.exists(directory)) {
147+
if (Files.exists(directory)
148+
&& shouldDeleteRegisteredDirectory(directory, maxAgeMillis)) {
148149
GeneralUtils.deleteDirectory(directory);
150+
registry.unregisterDirectory(directory);
149151
directoriesDeletedCount++;
150152
log.debug("Cleaned up temporary directory: {}", directory);
151153
}
@@ -275,6 +277,21 @@ private int cleanupUnregisteredFiles(
275277
return totalDeletedCount.get();
276278
}
277279

280+
private boolean shouldDeleteRegisteredDirectory(Path directory, long maxAgeMillis) {
281+
if (maxAgeMillis <= 0) {
282+
return true;
283+
}
284+
285+
try {
286+
long currentTime = System.currentTimeMillis();
287+
long lastModified = Files.getLastModifiedTime(directory).toMillis();
288+
return (currentTime - lastModified) > maxAgeMillis;
289+
} catch (IOException e) {
290+
log.debug("Could not check directory age, skipping cleanup: {}", directory, e);
291+
return false;
292+
}
293+
}
294+
278295
/** Get the system temp directory path based on configuration or system property. */
279296
private Path getSystemTempPath() {
280297
String systemTempDir =

app/common/src/main/java/stirling/software/common/util/TempFileManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public void deleteTempDirectory(Path directory) {
155155
if (directory != null && Files.isDirectory(directory)) {
156156
try {
157157
GeneralUtils.deleteDirectory(directory);
158+
registry.unregisterDirectory(directory);
158159
log.debug("Deleted temp directory: {}", directory.toString());
159160
} catch (IOException e) {
160161
log.warn("Failed to delete temp directory: {}", directory.toString(), e);

app/common/src/main/java/stirling/software/common/util/TempFileRegistry.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ public Path registerDirectory(Path directory) {
8585
return directory;
8686
}
8787

88+
/**
89+
* Unregister a temporary directory from the registry.
90+
*
91+
* @param directory The directory to unregister
92+
*/
93+
public void unregisterDirectory(Path directory) {
94+
if (directory != null) {
95+
tempDirectories.remove(directory);
96+
log.debug("Unregistered temp directory: {}", directory.toString());
97+
}
98+
}
99+
88100
/**
89101
* Register a third-party temporary file that requires special handling.
90102
*

app/common/src/test/java/stirling/software/common/service/TempFileCleanupServiceMoreTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,13 @@ void runsStartupCleanupWhenEnabled() throws IOException {
176176
class ScheduledCleanup {
177177

178178
@Test
179-
@DisplayName("deletes registered temp directories and reports counts")
179+
@DisplayName("deletes stale registered temp directories and reports counts")
180180
void deletesRegisteredDirectories() throws IOException {
181181
when(tempFileManager.cleanupOldTempFiles(anyLong())).thenReturn(2);
182182
Path regDir = Files.createDirectories(tempDir.resolve("registeredDir"));
183183
Files.createFile(regDir.resolve("inside.txt"));
184+
Files.setLastModifiedTime(
185+
regDir, FileTime.fromMillis(System.currentTimeMillis() - 2L * 60 * 60 * 1000));
184186
Set<Path> dirs = new HashSet<>();
185187
dirs.add(regDir);
186188
when(registry.getTempDirectories()).thenReturn(dirs);
@@ -193,6 +195,22 @@ void deletesRegisteredDirectories() throws IOException {
193195
verify(tempFileManager).cleanupOldTempFiles(anyLong());
194196
}
195197

198+
@Test
199+
@DisplayName("keeps a fresh registered temp directory")
200+
void keepsFreshRegisteredDirectory() throws IOException {
201+
when(tempFileManager.cleanupOldTempFiles(anyLong())).thenReturn(0);
202+
Path regDir = Files.createDirectories(tempDir.resolve("freshRegisteredDir"));
203+
Files.createFile(regDir.resolve("inside.txt"));
204+
Set<Path> dirs = new HashSet<>();
205+
dirs.add(regDir);
206+
when(registry.getTempDirectories()).thenReturn(dirs);
207+
lenient().when(registry.contains(any(File.class))).thenReturn(false);
208+
209+
withIsolatedUserHome(cleanupService::scheduledCleanup);
210+
211+
assertThat(Files.exists(regDir)).isTrue();
212+
}
213+
196214
@Test
197215
@DisplayName("skips a registered directory that no longer exists")
198216
void skipsMissingRegisteredDirectory() {

0 commit comments

Comments
 (0)