Conversation
apache#353) BackgroundCleaner.scanForLeftovers() iterated over all directories in the fast staging area and queued them for deletion. In setups where two concurrent builds share the same staging directory (e.g. the same ${project.build.directory}), one build's leftover scan could delete directories actively being used by the other. Fix: introduce a LEFTOVER_AGE_THRESHOLD_MS constant (30 s). scanForLeftovers() now reads the last-modified time of each staged directory and skips any directory younger than the threshold. A directory created by an ongoing concurrent build will always be younger than 30 s at the time of the scan; a directory left behind by a killed build will be older than 30 s in virtually all cases. If getLastModifiedTime() fails (unlikely, but defensive), the directory is also skipped to err on the side of caution. Also fix a pre-existing missing closing brace in CleanerTest (the test method batchRetryLogsWarningAfterRetryWhenStillFailing was missing its closing '}', causing a compile error that blocked spotless/checkstyle). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
gnodet-bot
approved these changes
Sep 26, 2026
gnodet-bot
left a comment
There was a problem hiding this comment.
Solid fix. The age-filter approach is well-chosen — simpler than PID markers, no hot-path I/O overhead, and the 30-second threshold is conservative enough to make false positives (deleting a concurrent build's directory) effectively impossible under normal conditions.
The three critical paths are correctly handled:
- Recent directories (
lastModified > threshold) → skipped - Old directories (
lastModified <= threshold) → queued for deletion getLastModifiedTime()failure → skipped (safe default)
Test coverage is adequate: both the positive and negative age-filter cases are exercised, and the existing scanForLeftoversDeletesOrphanedDirectories test is properly updated to set an old timestamp.
The CleanerTest fix (missing closing }) is a legitimate pre-existing compile error fix.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
BackgroundCleaner.scanForLeftovers()scans the fast staging directory at session start and queues any leftover directories for background deletion. It did not protect against the case where two concurrent builds share the same staging directory: one build's leftover scan could delete directories that are actively being used by the other build.Fixes #353.
Fix
Introduce a
LEFTOVER_AGE_THRESHOLD_MSconstant (30 seconds).scanForLeftovers()now reads the last-modified time of each staged directory and skips any directory younger than the threshold.BackgroundCleaneris initialised very early in the session, so there is no practical way a live build's staged directories are 30 s old at that point).getLastModifiedTime()fails (unlikely), the directory is also skipped — conservative, safe default.An age filter was chosen over the alternative PID-marker approach because:
/procor OS-specific PID checks).Also fixed
A pre-existing missing closing
}inCleanerTest.batchRetryLogsWarningAfterRetryWhenStillFailingthat was causing a compile error on the spotless/checkstyle phase.Tests
Two new tests in
BackgroundCleanerTest:scanForLeftoversSkipsRecentDirectories— a directory withlastModified = nowis not deleted.scanForLeftoversDeletesOldDirectories— a directory withlastModified = now − threshold − 60 sis deleted.The existing
scanForLeftoversDeletesOrphanedDirectoriestest is updated to set an old timestamp on the leftover directory (it would have been skipped by the new age filter with the defaultlastModified = nowfromcreateDirectory).