Thumbnail URL fix + archive daemon fix + batched initial loads #37

Merged
bvandeusen merged 0 commits from dev into main 2026-05-30 22:01:43 -04:00
bvandeusen commented 2026-05-30 22:01:36 -04:00 (Migrated from git.fabledsword.com)

Summary

Three UX-impacting fixes from 2026-05-30 afternoon. All "efficiency that hurt UX" reversals per the operator's standing principle.

  • adeee64 + 1eefed9 — Showcase + gallery initial loads now batch into 5-item chunks (12×5 for showcase, 10×5 for gallery) instead of one big 60/50 request. Total preserved. Items render progressively as each batch lands; combined with MasonryGrid's animateFromIndex, the showcase cascades batches in as they arrive instead of one big pop-in.
  • 44bb12a — Thumbnail URL derived from stored thumbnail_path instead of re-deriving from (sha256, mime). The MIME-based extension predicate disagreed with the thumbnailer's transparency-based predicate (.png if alpha else .jpg) → every PNG-without-alpha and every WebP-with-alpha 404'd despite the file existing. Backfill was never the bug — it checks the correct on-disk path; the URL construction was the broken side. All 8 callers updated. No DB migration or backfill rerun needed.
  • 810baf6 — Archive probe (safe_probe.probe_archive) switched from multiprocessing.Process to subprocess.run. The MP version crashed every import_archive_file in 49ms with AssertionError: daemonic processes are not allowed to have children (Celery prefork pool runs tasks in daemon processes; Python's multiprocessing forbids daemons from spawning children). Same crash isolation via subprocess; no daemon restriction. Layer-3 isolation added 2026-05-28 in [poison-pill resilience] was effectively a hard-blocker on the import path it was meant to protect.

No alembic migrations. New backend surface: backend/app/utils/_archive_probe_runner.py (subprocess entrypoint).

Test plan

After :latest rebuilds and compose restart:

  • Batched loads: Showcase + gallery initial fetches appear as ~5-item progressive cascades, not one big pop-in. Network panel shows multiple /api/showcase?limit=5 calls instead of one limit=60.
  • Thumbnail URL fix: Previously-broken thumbnails (gray placeholders in the operator's screenshot — image 44892, 44963, 44882, 44948, 48137, etc.) now render correctly. DevTools confirms the <img> src is the stored thumbnail_path and the file 200s.
  • Archive imports: Trigger an archive import (cbz / zip / rar / 7z). Completes end-to-end with media members extracted; no immediate AssertionError in 49ms; the import_archive_file task either succeeds or fails for a legitimate reason (bomb-guard, integrity, member-level).

🤖 Generated with Claude Code

## Summary Three UX-impacting fixes from 2026-05-30 afternoon. All "efficiency that hurt UX" reversals per the operator's standing principle. - **`adeee64` + `1eefed9`** — Showcase + gallery initial loads now batch into 5-item chunks (12×5 for showcase, 10×5 for gallery) instead of one big 60/50 request. Total preserved. Items render progressively as each batch lands; combined with MasonryGrid's `animateFromIndex`, the showcase cascades batches in as they arrive instead of one big pop-in. - **`44bb12a`** — Thumbnail URL derived from stored `thumbnail_path` instead of re-deriving from `(sha256, mime)`. The MIME-based extension predicate disagreed with the thumbnailer's transparency-based predicate (`.png` if `alpha` else `.jpg`) → every PNG-without-alpha and every WebP-with-alpha 404'd despite the file existing. Backfill was never the bug — it checks the correct on-disk path; the URL construction was the broken side. All 8 callers updated. **No DB migration or backfill rerun needed.** - **`810baf6`** — Archive probe (`safe_probe.probe_archive`) switched from `multiprocessing.Process` to `subprocess.run`. The MP version crashed every `import_archive_file` in 49ms with `AssertionError: daemonic processes are not allowed to have children` (Celery prefork pool runs tasks in daemon processes; Python's multiprocessing forbids daemons from spawning children). Same crash isolation via subprocess; no daemon restriction. Layer-3 isolation added 2026-05-28 in [poison-pill resilience] was effectively a hard-blocker on the import path it was meant to protect. No alembic migrations. New backend surface: `backend/app/utils/_archive_probe_runner.py` (subprocess entrypoint). ## Test plan After `:latest` rebuilds and compose restart: - [ ] **Batched loads:** Showcase + gallery initial fetches appear as ~5-item progressive cascades, not one big pop-in. Network panel shows multiple `/api/showcase?limit=5` calls instead of one `limit=60`. - [ ] **Thumbnail URL fix:** Previously-broken thumbnails (gray placeholders in the operator's screenshot — image 44892, 44963, 44882, 44948, 48137, etc.) now render correctly. DevTools confirms the `<img>` `src` is the stored `thumbnail_path` and the file 200s. - [ ] **Archive imports:** Trigger an archive import (cbz / zip / rar / 7z). Completes end-to-end with media members extracted; no immediate `AssertionError` in 49ms; the `import_archive_file` task either succeeds or fails for a legitimate reason (bomb-guard, integrity, member-level). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/FabledCurator#37