Skip to content

v0.9.2 — cleanup orphans + PID base names

Pre-release
Pre-release

Choose a tag to compare

@jamesgober jamesgober released this 13 May 22:15
· 7 commits to main since this release

mod-tempdir — v0.9.2 Design Note: cleanup_orphans

Local-only working document. Phase A output for the v0.9.2 milestone.
Concise on purpose; the heavy decision-by-decision write-up went
into DESIGN-v0.9.1.md and the patterns there
carry over.

Goal

Add cleanup_orphans(max_age_hours: u64) -> io::Result<usize>: a
top-level free function that sweeps the OS temp dir for default-prefix
entries this crate could have created, identifies orphans from dead
processes, and removes them.

Key calls

  1. Default-basename format gains a PID segment.

    • TempDir: .tmp-{pid}-{name12} (was .tmp-{name12} in 0.9.0).
    • NamedTempFile: .tmpfile-{pid}-{name12} (was .tmpfile-{name12}
      in 0.9.1).
    • with_prefix(p) is unchanged. cleanup_orphans never touches
      entries outside the default prefixes. The user's namespace is
      theirs to clean.
    • All existing tests that assert starts_with(".tmp-") /
      starts_with(".tmpfile-") keep passing: .tmp-1234-XYZ still
      starts with .tmp-. No test rewrites needed beyond the new ones.
  2. cleanup_orphans removal condition is (PID dead) AND (age >= max_age_hours). Both must hold.

  3. PID liveness check is platform-conditional, no deps added.

    • Linux: Path::new(&format!("/proc/{pid}")).exists().
    • macOS, Windows: liveness check is a no-op (treated as "dead"
      for the purpose of the AND). The age check is the sole gate
      on those platforms. Documented behavior. Picking
      max_age_hours larger than any legitimate process lifetime is
      the caller's responsibility on non-Linux.
    • Cross-platform PID introspection without libc/windows-sys
      is genuinely not available in std. Adding those deps is
      forbidden by the project rules. The honest cross-platform
      story is the asymmetric fallback above.
  4. Legacy 0.9.0 / 0.9.1 entries (no PID in name) are ignored.
    The parser requires a {digits}- segment after the prefix; entries
    without one are not eligible. Safer than trying to guess PIDs.

  5. Per-entry errors are silent, matching the Drop philosophy.
    The function returns the count of successful removals. The only
    Err path is failure to read the OS temp dir itself.

Test strategy

Five tests in tests/cleanup_orphans.rs. Each creates orphan entries
under unique-to-this-test bogus PIDs to avoid cross-test interference
with the shared temp dir.

  • Remove-eligible old orphan dir: removed.
  • Remove-eligible old orphan file: removed.
  • Recent default-prefix entry: kept (age guard).
  • Custom-prefix entry: kept (out of namespace).
  • Legacy-format default-prefix entry (no PID): kept (not eligible).
  • Linux-only: orphan under the current process's PID with backdated
    mtime: kept (live process guard).

File mtime backdating uses std::fs::File::set_modified, stable in
MSRV 1.75. If that turns out not to be in 1.75 after all, I'll fall
back to set_times.

Doc and CHANGELOG updates

  • README: bump the default-basename table, add the new function to
    the API listing, add a short "Cleaning up after crashes" section
    showing typical usage.
  • REPS.md §2: add the cleanup capability. §3: add the new function
    signature.
  • CHANGELOG.md [Unreleased]: ### Added + ### Changed (the
    basename format shift) + a migration sentence.

No version bump, no release ceremony. Accumulating into the next
release per the new workflow.

Full Changelog: v0.9.0...v0.9.2