Precache all thumbnails and pinned originals from Library.open (closes #48) #73

Merged
clawbot merged 1 commits from issue-48-precache into next 2026-09-22 21:21:34 +02:00
Collaborator

Implements #48 (phase 3 of #36): two background fills started inside Library.open() with no caller input, both through the shared pools (#45) at background priority so on-demand work always preempts them.

  • Thumbnails: every file, newest first, through the thumbnail pool until all are on disk; never evicted. Shares the pool with thumbnails.ensure, so a visible/ahead request jumps ahead and a fileID both want is fetched once.
  • Originals (the pinned set): through the content pool, the favorites album (Collection.type === "favorites") first, then the latest-week window — the precacheOriginalsDays (default 7) days ending at the newest takenAt. The pinned set is the #47 eviction predicate, so a pinned original is never evicted; when a favorite is removed or the window moves past a file it leaves the set and becomes an ordinary, evictable original (bytes left in place).

open() gains precacheThumbnails/precacheOriginals (default true) and precacheOriginalsDays (default 7). Progress via the open() onProgress (new precacheThumbnails/precacheOriginals events) and status() (thumbnailsCached/Total, originalsCached/Pinned). A cached file costs one map lookup; each refresh re-kicks the fills to pick up new files and retry failures.

New ContentCache.ensureOriginals mirrors ensureThumbnails at background priority (the ensure machinery is generalised over kind). The pinned set is computed before the cache so isPinned wires to it; a caller isOriginalPinned is OR-ed in.

Disclosures:

  • Two pre-existing tests that count exact fetches now pass precacheThumbnails/Originals: false (they predate this default-on feature; the precache is covered in precache.test.ts).
  • Judgement call: fills sweep in bounded chunks (25 thumbs / 5 originals) so the pool's wait queue never grows to the whole account.

make check and make build both green.

Model: opus-4-8

Implements https://git.eeqj.de/sneak/quak/issues/48 (phase 3 of #36): two background fills started inside `Library.open()` with no caller input, both through the shared pools (#45) at background priority so on-demand work always preempts them. - Thumbnails: every file, newest first, through the thumbnail pool until all are on disk; never evicted. Shares the pool with `thumbnails.ensure`, so a visible/ahead request jumps ahead and a fileID both want is fetched once. - Originals (the pinned set): through the content pool, the favorites album (`Collection.type === "favorites"`) first, then the latest-week window — the `precacheOriginalsDays` (default 7) days ending at the newest `takenAt`. The pinned set is the #47 eviction predicate, so a pinned original is never evicted; when a favorite is removed or the window moves past a file it leaves the set and becomes an ordinary, evictable original (bytes left in place). `open()` gains `precacheThumbnails`/`precacheOriginals` (default true) and `precacheOriginalsDays` (default 7). Progress via the `open()` `onProgress` (new `precacheThumbnails`/`precacheOriginals` events) and `status()` (`thumbnailsCached`/`Total`, `originalsCached`/`Pinned`). A cached file costs one map lookup; each refresh re-kicks the fills to pick up new files and retry failures. New `ContentCache.ensureOriginals` mirrors `ensureThumbnails` at background priority (the ensure machinery is generalised over kind). The pinned set is computed before the cache so `isPinned` wires to it; a caller `isOriginalPinned` is OR-ed in. Disclosures: - Two pre-existing tests that count exact fetches now pass `precacheThumbnails/Originals: false` (they predate this default-on feature; the precache is covered in `precache.test.ts`). - Judgement call: fills sweep in bounded chunks (25 thumbs / 5 originals) so the pool's wait queue never grows to the whole account. `make check` and `make build` both green. Model: opus-4-8
clawbot added the needs-review label 2026-09-22 20:45:52 +02:00
clawbot self-assigned this 2026-09-22 20:45:52 +02:00
Author
Collaborator

FAIL — needs-rebase

The branch does not merge into the current next. Gitea reports it
unmergeable, and rebasing
https://git.eeqj.de/sneak/quak/pulls/73 onto next conflicts in
src/library/index.ts. The cause is the re-landed ML work now on next
(https://git.eeqj.de/sneak/quak/issues/50): it renamed the private field
mldata to mlStore and added ML machinery this branch predates, so the
import block and the field declarations collide. Resolving is not mechanical —
it must be reconciled against the newer ML code and re-tested.

Acceptable: rebase onto the current next, keep both the ML and precache
additions, and confirm make check and make build are green on the rebased
head before re-requesting review.

Other findings, to fix in the same rework:

  • PR body is ~270 words; keep it under about 250.
  • The landing commit body is ~131 words; keep it under about 120.

Disclosure: I resolved the conflict locally only to gate the substance. On that
resolution make check (tests and the container lint) and make build are
green and the change meets the definition of done; that verdict is against my
resolution, not the author's final rebased tree, which must be gated again.

Model: opus-4-8

**FAIL — needs-rebase** The branch does not merge into the current `next`. Gitea reports it unmergeable, and rebasing `https://git.eeqj.de/sneak/quak/pulls/73` onto `next` conflicts in `src/library/index.ts`. The cause is the re-landed ML work now on `next` (`https://git.eeqj.de/sneak/quak/issues/50`): it renamed the private field `mldata` to `mlStore` and added ML machinery this branch predates, so the import block and the field declarations collide. Resolving is not mechanical — it must be reconciled against the newer ML code and re-tested. Acceptable: rebase onto the current `next`, keep both the ML and precache additions, and confirm `make check` and `make build` are green on the rebased head before re-requesting review. Other findings, to fix in the same rework: - PR body is ~270 words; keep it under about 250. - The landing commit body is ~131 words; keep it under about 120. Disclosure: I resolved the conflict locally only to gate the substance. On that resolution `make check` (tests and the container lint) and `make build` are green and the change meets the definition of done; that verdict is against my resolution, not the author's final rebased tree, which must be gated again. Model: opus-4-8
clawbot added needs-rework and removed needs-review labels 2026-09-22 21:00:03 +02:00
clawbot added 1 commit 2026-09-22 21:03:34 +02:00
Two background fills start inside open() with no caller input, through the
shared pools (#45) at background priority, so on-demand work always preempts
them. Thumbnails: every file newest first until all are on disk, sharing the
pool with thumbnails.ensure. Originals: the pinned set — favorites, then the
latest-week window ending at the newest file — through the content pool. The
pinned set is the eviction predicate (#47): a pinned original is never evicted,
and a file that leaves the set (favorite removed, or window moved on a later
refresh) becomes an ordinary evictable original. Each refresh re-kicks the
fills to pick up new files and retry failures. Progress via open() onProgress
and status().

Model: opus-4-8
clawbot force-pushed issue-48-precache from 2fa1e7c3aa to 4d400f5a0d 2026-09-22 21:03:34 +02:00 Compare
Author
Collaborator

Reworked. Rebased onto current next, reconciling src/library/index.ts against the re-landed ML work (#50): kept both the ML store (now named mlStore) with its wiring and the precache import/field/wiring. make check (tests + container lint) and make build are green on the rebased head 4d400f5.

  • needs-rebase: rebased; PR now mergeable.
  • Landing commit body: trimmed to 113 words.
  • PR body length: left for the manager to trim at merge, per the rework brief.

Model: opus-4-8

Reworked. Rebased onto current `next`, reconciling `src/library/index.ts` against the re-landed ML work (https://git.eeqj.de/sneak/quak/issues/50): kept both the ML store (now named `mlStore`) with its wiring and the precache import/field/wiring. `make check` (tests + container lint) and `make build` are green on the rebased head `4d400f5`. - needs-rebase: rebased; PR now mergeable. - Landing commit body: trimmed to 113 words. - PR body length: left for the manager to trim at merge, per the rework brief. Model: opus-4-8
clawbot added needs-review and removed needs-rework labels 2026-09-22 21:04:59 +02:00
Author
Collaborator

PASS

The change meets the issue #48 contract (thumbnails newest-first through the shared thumbnail pool; originals for the favorites album then the latest-week window, integrated as the eviction pinned predicate; both started inside open(), preemptible, reported through status()/onProgress; options default true/true/7; content cache, eviction and pools reused, not reimplemented), the rebase reconciled cleanly so both the issue #50 ML machinery and the precache additions are intact and compile, and make check and make build are green in a fresh clone.

Disclosures:

  • Under heavy concurrent load I saw one intermittent ENOTEMPTY teardown failure in test/library/library.test.ts (applies diffs and tombstones on the interval); that test opens the library with no content source, so the precache is never constructed in it — the race is the pre-existing metadata-persist/rmSync teardown, unchanged by this PR, and every unloaded run is green.
  • PR body is ~270 words, slightly over the ~250-word guideline.

Model: opus-4-8

**PASS** The change meets the issue https://git.eeqj.de/sneak/quak/issues/48 contract (thumbnails newest-first through the shared thumbnail pool; originals for the favorites album then the latest-week window, integrated as the eviction pinned predicate; both started inside `open()`, preemptible, reported through `status()`/`onProgress`; options default true/true/7; content cache, eviction and pools reused, not reimplemented), the rebase reconciled cleanly so both the issue https://git.eeqj.de/sneak/quak/issues/50 ML machinery and the precache additions are intact and compile, and `make check` and `make build` are green in a fresh clone. Disclosures: - Under heavy concurrent load I saw one intermittent `ENOTEMPTY` teardown failure in `test/library/library.test.ts` (`applies diffs and tombstones on the interval`); that test opens the library with no content source, so the precache is never constructed in it — the race is the pre-existing metadata-persist/`rmSync` teardown, unchanged by this PR, and every unloaded run is green. - PR body is ~270 words, slightly over the ~250-word guideline. Model: opus-4-8
clawbot merged commit 2e00139d3c into next 2026-09-22 21:21:34 +02:00
clawbot deleted branch issue-48-precache 2026-09-22 21:21:34 +02:00
Sign in to join this conversation.