Skip to content

Recycled-rowid cache hardening: remaining review findings from #1369 #1371

Description

@jss367

Follow-ups deliberately deferred when #1369 merged. All are real but narrow — Windows file-lock and clock-skew scenarios, or additional id-keyed cache families — and none affects the core fix (a new photo row purging derivatives left by a previous owner of its recycled rowid).

Context: photos.id is INTEGER PRIMARY KEY without AUTOINCREMENT, so SQLite hands the next insert max(rowid) + 1 and freed ids come straight back. Everything under ~/.vireo keyed by bare photo id is therefore inheritable. #1369 covered thumbnails, previews, working copies, masks, prepared renders, external-DNG, external-edits, and offline originals.

Open findings- ** Purge recycled iNaturalist upload renders** — vireo/preview_cache.py:315 (thread)

  • ** Handle snapshot-directory errors before committing recipe moves** — vireo/scanner.py:622 (thread)
  • ** Invalidate regeneration sidecars after recipe edits** — vireo/app.py:24941 (thread)
  • ** Probe variants without enumerating unreadable directories** — vireo/preview_cache.py:460 (thread)
  • ** Retain the RAW path when pegging display caches** — vireo/app.py:30542 (thread)
  • ** Catch errors raised while iterating scandir** — vireo/preview_cache.py:395 (thread)

Notes

  • edit-masks/ is deliberately excluded from the id-keyed purge — those snapshots are content-addressed and local_masks.gc_edit_masks owns them by ref. Purging them by id destroyed data (see Stop recycled photo rowids from inheriting the old photo's cached images #1369 discussion).
  • Two judgment calls made in Stop recycled photo rowids from inheriting the old photo's cached images #1369 that could be revisited here:
    • serve_mask now requires a photo_masks / photos.mask_path row rather than serving any file that exists. On the live library 915 of 916 unreferenced bare masks belonged to dead photo ids; 1 belonged to a live photo.
    • The <id>_regen.jpg sidecar in serve_thumbnail (serves a fresh render when the stale thumbnail is locked, rather than 404ing). It is the most intricate part of that diff and generated five follow-up findings of its own; the simpler alternative is to 404.
  • Declined in Stop recycled photo rowids from inheriting the old photo's cached images #1369: refusing the recycled insert / stopping ingest when a cache file cannot be invalidated. That trades a narrow wrong-pixels window for failed imports, and the photo row is what makes the file recoverable at all.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions