diff --git a/containers/120-mule-images.md b/containers/120-mule-images.md index c8dd6c3..56353b6 100644 --- a/containers/120-mule-images.md +++ b/containers/120-mule-images.md @@ -80,12 +80,21 @@ For pushes from inside the LXC, gitea creds at `/etc/mule-deploy/git-credentials ## Changelog -### 2026-05-10 — backend out of dev mode -`docker-compose.yml` backend `command` was running `uvicorn … --reload` (single worker, file-watcher). Page loads fanned out ~15 parallel API calls that all serialized on one event loop. Switched to `--workers 2 --proxy-headers`. Verified: `docker inspect mulita-backend --format '{{.Config.Cmd}}'` shows the new flags; two uvicorn worker processes visible. +### 2026-05-10 — `photos.hubris.network` perf sweep -Gotcha: the `docker compose up -d --build` in `deploy.sh` did not recreate the backend after this commit — only `--build` rebuilds images, and the `command` change is runtime-only. Had to run `docker compose up -d --no-deps --force-recreate backend` manually. Consider adding `--force-recreate` to `deploy.sh` if compose-only changes become common. +User reported slow load. Five fixes shipped, in order: -Still on the table for further `photos.hubris.network` perf work: pre-generate `/data/proxies` web-sized webps (currently empty volume → first open of any RAW/HEIC is a sync decode), shrink the 500-photo default page size, and back off `worker-status` / `scan/status` polling when idle. +1. **Backend out of dev mode.** `docker-compose.yml` `command:` was running `uvicorn … --reload` (single worker, file-watcher). Page loads fan out ~15 parallel API calls; they all serialized on one event loop. → `--workers 2 --proxy-headers`. Two uvicorn worker procs now. +2. **iPhone Apple ProRAW / Linear DNG decode fixed.** rawpy 0.26.1 + LibRaw 0.22 rejects Apple Linear DNG (`Photometric Interpretation: Linear Raw`, 8-bit) as "Unsupported file format or not RAW file". Those files are TIFF containers with developed RGB inside and have no embedded preview to fall back to. Added PIL `Image.open(src_path)` as the last fallback in both `_generate_proxy_webp` (routers/photos.py) and `process_raw_image` (tasks/thumbs.py). ~1,300 iPhone DNGs were 415-ing on every detail view; now decode in <1s via PIL. +3. **Reconcile DB with disk (renamed-folder case).** `prune_missing_photos` was skipping all 4,154 orphaned photo rows under SourceRoot `Taco and Muli - 2024 onward` (renamed in Nextcloud to `Photo Archive 2004-2024`) because the leaf path didn't resolve and the code assumed "drive unmounted → must skip". Added `_sr_state()` to classify as `present` / `renamed` (parent mount fine, leaf gone) / `unmounted` (parent inaccessible). Only `unmounted` still skips. Two stale source roots logged with a clearer hint pointing at `POST /api/v1/library/maintenance/prune-missing`. User has not yet been asked to run that — endpoint is ready when they are. +4. **Frontend page size + idle polling.** `usePhotosQuery.ts` was first-fetching `per_page=500` (slow paint + 500 thumb requests at once). Split into `PER_PAGE_INITIAL=100` for first paint, `PER_PAGE_BACKGROUND=500` for the cursor-chain prefetch. Idle polling for `scan-status` and `worker-status` (`useScanActivity.ts`, `ScanProgress.tsx`) bumped from 10s/15s to 30s/30s while idle; active cadence (2s/3s) unchanged. +5. **Partial index on `photos`.** Default list query `WHERE NOT is_trashed AND NOT is_hidden ORDER BY taken_at DESC NULLS LAST, id DESC LIMIT N` was doing a seq-scan + top-N heapsort (~25ms standalone, worse under concurrency). Added migration `0017_photos_list_index` creating `ix_photos_list_visible` (partial index on the sort key, restricted to visible rows). EXPLAIN now shows an Index Only Scan → **24.7ms → 0.097ms**, ~250× speedup. + +**Deploy gotcha (repeated).** The `docker compose up -d --build` in `deploy.sh` does not recreate the backend when only runtime config (`command:` or env-only changes) or migration files change without changing the Dockerfile-bake outcome. Forced recreation with `docker compose up -d --no-deps --force-recreate backend` twice this session. **Action item:** add `--force-recreate` (or at least `--force-recreate backend` when backend files changed) to `/opt/mule-deploy/deploy.sh` so future deploys are reliable. + +**Data drift still outstanding.** 4,154 photo rows + 1 unregistered folder (`Photo Archive 2004-2024`) on disk that's not a SourceRoot. The reconcile endpoints now work — user decides when to call them. The new folder needs to be added as a SourceRoot via the Settings UI before its files will be indexed. + +**Proxy cache still empty** (`mule-image_proxies_data` volume is 4 KB). Pre-generating ~500–1,500 WebP proxies for non-web-safe formats would make first-open of every RAW/HEIC photo instant. Deferred — needs a one-shot script and the disk-space tradeoff isn't worth it until the data-drift reconcile happens first. ### 2026-04-28 — wiki entry created Initial documentation.