Repository navigation
fix(studio): a thumbnail reader forgets a start's failures after a minute - #6642
Conversation
…nute A pooled thumbnail reader lives for as long as clips keep asking it, and each start byte has a retry budget of two. That budget never reset, so two transient failures at one start early in a session made a third, twenty minutes later after the cache evicted it, give up at once: the reader retired and the clip showed an error. A start's failures now count for a minute. One bout of retries (8 s stalls, 0.5 s and 1 s waits) fits inside it, so a start that keeps failing still gives up; one met again much later starts afresh. Clearing the count when a read from that start delivers bytes would not do: a server that ignores Range sends bytes 0 onward again before it breaks at the same byte, and would retry forever. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…t a comment Co-Authored-By: Claude Opus 5.5 <[email protected]>
Edit accuracy: accurate 271 (base branch 271), smooth 102 of thoseThe gate passes. Quarantined, measured but not gated (0) |
…leanly, not after a minute The one-minute window only held while each attempt took under a minute. An attempt has no limit before its answer, and a body that keeps sending never stalls, so a server that ignores Range, sends slowly and breaks past a minute re-downloaded from 0 forever. A start's failures are now forgotten when a read from it ends cleanly: its body finishes, or mediabunny cancels it at its target. A server that breaks before the target never ends a read cleanly, so its budget still runs out, however slowly it fails. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
Verdict: APPROVE · 1 resolved, 0 open, 1 new · 41e739b9 → cd7650a3
The new finding ↓ isn't a regression from main, but the cancel-at-target reset doesn't fire under mediabunny as it runs today. CI, CodeQL, Comments and PR captures are green on this head.
— Genesis
…esets its start's budget mediabunny's UrlSource never cancels the body: once a read reaches its target, _runWorker aborts the signal it passed in, and the pending pull fails with an AbortError. So the reset on cancel never fired, and any open bytes=N- read stopped at its target kept its start's failures. The request now listens on its own signal, which follows mediabunny's and is unlinked once the read ends: an abort while live counts as a clean end only when mediabunny's signal is the one aborted, never a stall or a dispose. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
Verdict: APPROVE · 1 resolved, 0 open, 0 new · cd7650a3 → aa3cf5fe
I checked the fix against a real mediabunny 1.45.3 UrlSource. Two failures at a start, then a read stopped at its target, now leaves that start's count at zero. The same check fails on cd7650a3. CI, CodeQL, Comments and PR captures are green on this head.
— Genesis
Summary
Follow-up to #6629, from Genesis's review. A pooled thumbnail reader's per-start retry budget never reset, so two transient failures at one start early in a session made a third one, much later, give up at once. That retired the reader and showed the clip as an error.
A start's failures are now forgotten when a read from that start ends cleanly: either its body finishes, or mediabunny stops it at its target. mediabunny never cancels the body;
_runWorkeraborts the signal it passed in. So the request listens on its own signal, which follows mediabunny's and is unlinked once the read ends, and counts an abort as clean only when mediabunny's signal is the one aborted: never a stall (8 s silence) or a dispose (cancelReads).I ruled out two other designs:
gives up on a server that ignores Range and breaks at the same bytefails under that version.No visible change
Retry bookkeeping in
mediaFetch.ts: 10 lines, no.tsx,.cssor.html. A thumbnail looks the same; it just stops failing when a start that once failed twice comes back later.What I measured
mediaFetch.test.ts: 32 pass. Four of those tests are new:_runWorkerdoes at its target) resets the budget;unlinks every request from mediabunny's signal however it endscaught a first version that listened on mediabunny's signal directly.What I did NOT exercise
fetch.🤖 Generated with Claude Code