Everything written this session that has not been through the device: rounds 43 to 48 (each patch adversarially verified, 43's transient-notice expectation fixed), a partial round 49, the pipeline scripts, the Android Auto design and the icon comparison mock. Also the two harness changes that were never A/B'd — adaptive waits, which may only shorten a declared wait and never lengthen it, and a ship that runs the mock walk and the deploy at the same time. The A/B and its 255-step baseline are in handoff/tools; main stays at what the phone has actually walked.
53 lines
3.5 KiB
Plaintext
53 lines
3.5 KiB
Plaintext
android: the long session — what the app is still holding after an hour
|
||
|
||
Every walk this project has ever run is minutes long, and nothing in the port
|
||
had been looked at for a leak. Driving the real bundle lap after lap says two
|
||
useful things. The first is that the obvious answer is wrong: the naive
|
||
add-minus-remove listener counter climbs about twelve a lap, and every one of
|
||
those is a `.screen` element that `{#key nav.seq}` threw away — count only
|
||
what is still attached to window, document or a connected element and it is
|
||
flat, lap for lap, and so are the intervals. The second is that exactly two
|
||
things grow without a limit. `art.svelte.js` kept every cover it had ever
|
||
fetched for the WebView's lifetime — one browse of a 114-cover library takes
|
||
it from 5 keys to 114 and gives nothing back, at roughly 63 KB of base64
|
||
each — and `pls.covers` is keyed `id:revision`, so every playlist edit
|
||
stranded a 360 px data URL under a key nothing could ever read again.
|
||
|
||
Both are bounded at the desktop's own numbers rather than at invented ones:
|
||
`ART_THUMB_CACHE_MAX` 512 and `ART_THUMB_CACHE_MAX_CHARS` 16 MiB out of
|
||
`state.svelte.js`, oldest first. Two rules the desktop does not need are
|
||
added, because its callers ask through `getArt(path)` while the phone's
|
||
templates index the map: the entry that just landed is never dropped, and
|
||
neither is one a connected `<img>` is painting — `Cover`'s `visible` action
|
||
re-arms only on a path prop change, so an evicted cover that is still mounted
|
||
would stay a disc for good. Built with the cap forced to 8 and scrolled
|
||
through eighteen screens of a 140-card Library grid, the map sat at 61 —
|
||
spared, every one of them, for being painted — and not one cover on screen
|
||
lost its image; at the shipped 512 a whole library walk runs the trim zero
|
||
times. The playlist covers need no policy at all: the new revision drops the
|
||
old ones, which are unreachable by construction.
|
||
|
||
The verification is the round. `artTally()` on the handle reports the map and
|
||
its side tables, which are module-private; seventeen probe fields carry that,
|
||
the catalog's ten session maps, the queue, the transfers and the DOM on every
|
||
step of both walks; and seven mock steps install a live listener and timer
|
||
registry in the page — by a step, not by `addScriptToEvaluateOnNewDocument`,
|
||
which the first-run block's reloads would throw away — drive two warm laps, a
|
||
baseline and nine more, assert the census, and take the registry back out so
|
||
nothing appended after this block inherits a patched platform. Installed that
|
||
late it can only see what is registered from that moment on, so its absolute
|
||
counts are small and are not asserted as a census; what is asserted is the
|
||
delta across the nine laps, and that it fires was proved by planting a
|
||
listener and an interval stranded once a lap: `grewEars` 0 → 9, `grewTicks`
|
||
0 → 9, and the step fails. As it ships, over those nine laps, the listeners
|
||
and the intervals moved by 0, the art map grew 17 against a headroom of 80
|
||
and the catalog 5 against 24, and the DOM ended smaller than it started.
|
||
`tallyTimers` is a ceiling and not a delta, and says so: every track start
|
||
schedules a 47-second recents refresh, so a walk this fast keeps a handful
|
||
pending, and making it sharp would cost a fifty-second quiet period. The
|
||
catalog maps, `tracksCache` and that recents timeout are named in ANDROID.md
|
||
as left alone on purpose — evicting a catalog entry is not safe while
|
||
`Artist.svelte` looks one up inside `untrack`. Nothing new on the phone leg:
|
||
the registry is never installed there, those three fields read −1, and
|
||
`artTally()` is a pure read.
|