Clean up stale temp directories from previous OnDiskLoader invocations#366
Merged
Conversation
LogReaderState now acquires a .lock file (FileShare.None) in its BaseDirectory on construction. After acquiring its own lock, it enumerates sibling directories in the same parent and deletes any that are stale (lock file not held or absent). This ensures that temp directories left behind by previous tool invocations (where the AssemblyLoadContext was never collected) are cleaned up on the next run without risking deletion of directories actively in use by concurrent processes. Co-authored-by: Copilot App <[email protected]>
…NotFoundException - Fix replay/export commands to separately dispose LogReaderState when passed explicitly (OwnsLogReaderState was false, state leaked) - Add DirectoryNotFoundException catch in second Dispose try/catch block - Mark ReplayOnDiskCleansStaleTempDirectories as UnixFact since Windows cannot delete directories with ALC-locked DLLs Co-authored-by: Copilot App <[email protected]>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #366 +/- ##
==========================================
- Coverage 95.81% 95.79% -0.03%
==========================================
Files 56 56
Lines 7703 7759 +56
Branches 898 905 +7
==========================================
+ Hits 7381 7433 +52
- Misses 179 183 +4
Partials 143 143 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Custom base directories are managed by the caller and don't need the lock-based cleanup protocol. This fixes ExportUtilTests on Windows where Root.EmptyDirectory() tried to delete the state/ dir containing the held lock file. Co-authored-by: Copilot App <[email protected]>
- Add DisposeCleansUpLockFile test verifying lock file deleted on dispose - Add CleanupDeletesStaleSiblingOnConstruction test - Add CleanupDeletesStaleSiblingWithUnlockedLockFile test - Add GetCompilerLogTempDirectory helper tests (default and custom paths) Co-authored-by: Copilot App <[email protected]>
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.
When
OnDiskLoadercreates temp directories for on-disk analyzer loading, cleanup relies onAssemblyLoadContextfinalization -- which is not guaranteed to run. Over time, stale directories accumulate under the temp path.Approach
Uses a file-lock sentinel to prove directory ownership:
LogReaderStateacquires a.lockfile (FileShare.None) in itsBaseDirectoryon construction. The OS releases this lock automatically on process exit (even crashes).LogReaderStateenumerates sibling directories in the same parent and callsCommonUtil.CleanupStaleTempDirectories()which probes each.lockfile:Dispose(), the lock file is released and deleted so the directory can be cleaned byDeleteDirectoryIfEmptyor by the next invocation's cleanup pass.This is self-contained in
LogReaderState-- no explicit startup call needed. Any code path that creates aLogReaderState(CLI commands, library consumers) will automatically clean up stale siblings.Other changes
CommonUtil.GetCompilerLogTempDirectory(string? basePath = null)helper to centralize the temp directory path logic.ReplayOnDiskCleansStaleTempDirectoriesthat verifies a second tool invocation cleans up the stale directory left by an on-disk analyzer run.