fix(clean): sweep abandoned Foundation temp directories - #38
Merged
Conversation
Opening a SwiftData store on a file URL makes Foundation create an item replacement directory in the per-user temp root and never remove it, roughly six per run of a Swift test suite that touches a file-backed container. They accumulate without bound, and macOS reports that path as "System Data", so nothing an operator looks at shows them growing. One reading passed ten thousand entries across two gigabytes. The existing sweep never sees them. Runner temp is redirected per runner and wiped wholesale, which is safe precisely because nothing else writes there; these land in the shared per-user root instead, from CI and from local development alike. So this sits with the docker volume prune, which is already machine-wide housekeeping rather than per-runner. Two things keep it safe on a shared path: only entries matching Foundation's own name are touched, and only ones untouched for three days. These directories exist for the moment of an atomic file replacement, so one that has sat that long was abandoned by a process no longer running, and anything a live job created is far too recent to match. Three days rather than something tighter is deliberate. It bounds the growth, which is what the defect actually is, without betting that no process on a shared machine holds one open for a while.
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.
Closes #37.
Opening a SwiftData store on a file URL makes Foundation create an item-replacement directory in the per-user temp root and never remove it — roughly six per run of a Swift test suite that touches a file-backed container. They accumulate without bound, and macOS reports that path as "System Data", so nothing an operator looks at shows them growing.
The existing sweep never sees them. Runner temp is redirected per runner and wiped wholesale, which is safe precisely because nothing else writes there; these land in the shared per-user root instead, from CI and local development alike.
So this sits with the dangling-Docker-volume prune, which is already machine-wide rather than per-runner.
What makes it safe on a shared path
Three days rather than something tighter is deliberate: it bounds the growth, which is what the defect is, without betting that nothing on a shared machine holds one open for a while.
Verified
Measured on the development machine: 711 entries present, 18 older than three days, 525 recent ones untouched, and nothing outside the
TemporaryDirectory.*pattern matched.The block itself was exercised against a sandbox containing two old Foundation directories, one recent one, and one old directory that is not Foundation's. It removed the two, kept the recent one, and kept the one that was not ours — which is the property that matters on a shared path.
bash -nclean.runpool cleanwas not run against the live pools, since it prunes real runner state and CI was active.