Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Clean up stale temp directories from previous OnDiskLoader invocations#366

Merged
jaredpar merged 4 commits into
mainfrom
jaredpar-cleanup-stale-temp-dirs
Jul 1, 2026
Merged

Clean up stale temp directories from previous OnDiskLoader invocations#366
jaredpar merged 4 commits into
mainfrom
jaredpar-cleanup-stale-temp-dirs

Conversation

@jaredpar

@jaredpar jaredpar commented Jul 1, 2026

Copy link
Copy Markdown
Owner

When OnDiskLoader creates temp directories for on-disk analyzer loading, cleanup relies on AssemblyLoadContext finalization -- 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:

  • LogReaderState acquires a .lock file (FileShare.None) in its BaseDirectory on construction. The OS releases this lock automatically on process exit (even crashes).
  • On construction, after acquiring its own lock, LogReaderState enumerates sibling directories in the same parent and calls CommonUtil.CleanupStaleTempDirectories() which probes each .lock file:
    • Lock acquirable or absent -- directory is stale -- delete recursively
    • Lock denied -- directory is in active use -- skip
  • On Dispose(), the lock file is released and deleted so the directory can be cleaned by DeleteDirectoryIfEmpty or by the next invocation's cleanup pass.

This is self-contained in LogReaderState -- no explicit startup call needed. Any code path that creates a LogReaderState (CLI commands, library consumers) will automatically clean up stale siblings.

Other changes

  • Added CommonUtil.GetCompilerLogTempDirectory(string? basePath = null) helper to centralize the temp directory path logic.
  • Added unit tests covering stale deletion, locked-dir skip, and missing-lock scenarios.
  • Added end-to-end test ReplayOnDiskCleansStaleTempDirectories that verifies a second tool invocation cleans up the stale directory left by an on-disk analyzer run.

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]>
@jaredpar jaredpar enabled auto-merge (squash) July 1, 2026 21:28
…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]>
@jaredpar jaredpar disabled auto-merge July 1, 2026 21:56
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.52459% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.79%. Comparing base (ea4ff25) to head (614c6ea).

Files with missing lines Patch % Lines
src/Basic.CompilerLog.Util/LogReaderState.cs 77.41% 7 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

jaredpar and others added 2 commits July 1, 2026 15:05
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]>
@jaredpar jaredpar merged commit 51a4eea into main Jul 1, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant