A display opened over plain http:// on a LAN address is not a secure
context, so the browser gives it no Cache Storage. The media cache then
fell back to the in-memory test double, which remembered only each
slide's signed delivery URL and still reported it as cached. Online that
looked identical. Offline, the next slide's URL could not be loaded, the
slide was marked unusable, and local continuation kept landing on the
image already on screen. The wall froze until the network returned.
Without Cache Storage, the browser media cache now fetches and holds the
bytes in page memory as object URLs (one per key, revoked on prune,
replace and stop), so a running display keeps cycling through what it
already has. Nothing persists across a reload; on such an origin the
platform cannot cache the display page either.
Regression tests: the media cache on an origin without Cache Storage,
and the whole controller on an ordered fake clock, cycling for six slide
intervals with the network gone and then handing back to the server.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The Cache Storage media cache minted a new object URL on every lookup
and never revoked any. Every state refresh looks up every cached slide,
so a running display pinned one more blob per slide per refresh until
the browser refused its requests with net::ERR_INSUFFICIENT_RESOURCES.
It then showed its offline banner on a working network. Two tabs leaked
twice as fast, and real photographs fill blob storage far sooner than
test slides.
Each cache entry now has exactly one object URL:
- every lookup reuses it;
- pruning or replacing the entry revokes it;
- release(), new on SignageMediaCache, revokes all of them, and the
controller calls it on stop once the stage is gone.
Two lookups of one slide racing each other keep the first URL and make
no second one. The in-memory cache has nothing to give back.
Co-Authored-By: Claude Opus 5.5 <[email protected]>