docs: record Phase 21 (windowed streaming) as landed; note Direction A to B pivot
Move Phase 21 from PLAN to COMPLETED with the as-built record, and annotate the spec that Direction B shipped after WASM fetch buffering defeated A.
This commit is contained in:
@@ -1,9 +1,24 @@
|
||||
# Phase 21 — Windowed Streaming Buffer (bounded client memory for long streams)
|
||||
|
||||
Product spec. Status: **design / framing — reconciled to as-built Phase 18 (two decode paths);
|
||||
implementation-ready pending Daniel's open-question calls (OQ1–OQ4 product; OQ6–OQ7 staff-engineer
|
||||
architecture).** Author: product-designer. Date: 2026-06-23 (reconciliation pass after Phase 18 landed).
|
||||
**No code has been written by this doc.**
|
||||
Product spec. Status: **LANDED 2026-06-24 on `streaming-overhaul`.** See `COMPLETED.md` for the full
|
||||
as-built record. Author: product-designer. Date: 2026-06-23 (reconciliation pass after Phase 18 landed).
|
||||
|
||||
> **AS-BUILT NOTE — Direction A→B pivot (2026-06-24).** This spec recommended **Direction A** (sliding
|
||||
> window on one open-ended forward stream, pausing `ReadAsync`/the segment loop to backpressure the
|
||||
> socket) and held **Direction B** (discrete bounded `Range: bytes=start-end` segments, §3.2) as the
|
||||
> documented fallback. **21.4 browser validation proved Direction A insufficient for Blazor WASM:** the
|
||||
> browser `fetch` API buffers the entire HTTP response body regardless of read pace — pausing reads
|
||||
> bounded the *decode* but not the *network download*, so the whole ~970 MB body accumulated in browser
|
||||
> memory even with the application decoding only a window of it. **We shipped Direction B.** The forward
|
||||
> stream now issues sequential 4 MB bounded Range requests (`SegmentSizeBytes = 4 MB`), fetched via
|
||||
> `RunSegmentedStreamAsync` in `StreamingAudioPlayerService`, each issued only after
|
||||
> `PlaybackScheduler.evaluateProductionPause()` clears below low-water. Browser holds ~one 4 MB segment
|
||||
> of raw bytes; 21.4 confirmed network-memory bounding in Daniel's browser run. The decode-side windowing
|
||||
> (21.1/21.2) is unchanged and pairs with Direction B; seek/refill converge on the same segmented loop
|
||||
> via `RecoverFromFailedRefill`. Direction A is recorded as tried-in-validation and found insufficient
|
||||
> for the WASM `fetch` runtime. Sections §3.2–§3.3 below retain the original A vs. B vs. C analysis as
|
||||
> the decision record; **Direction B is what shipped.**
|
||||
|
||||
Surface: **public listener site only** (`DeepDrftPublic.Client` player stack + `DeepDrftPublic`
|
||||
TypeScript audio interop). No CMS (`DeepDrftManager`) change. No data-model or schema change. The one
|
||||
server touch is **reuse, not new surface**: the existing `DeepDrftAPI` HTTP `Range: bytes=X-`
|
||||
|
||||
Reference in New Issue
Block a user