- From: Mattias Buelens <notifications@github.com>
- Date: Tue, 30 Mar 2021 16:16:04 -0700
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/pull/1114/review/624775850@github.com>
@MattiasBuelens commented on this pull request. > + if (forBranch2 === true) { + if (canceled1 === false) { + const clonedChunk = CloneArrayBufferView(chunk); + ReadableByteStreamControllerEnqueue(branch1._controller, clonedChunk); + } + if (canceled2 === true) { + chunk = new Uint8Array(chunk.buffer, chunk.byteOffset, 0); + } + ReadableByteStreamControllerRespondWithNewView(branch2._controller, chunk); + } else { + if (canceled2 === false) { + const clonedChunk = CloneArrayBufferView(chunk); + ReadableByteStreamControllerEnqueue(branch2._controller, clonedChunk); + } + if (canceled1 === true) { + chunk = new Uint8Array(chunk.buffer, chunk.byteOffset, 0); > This seems like a significant footgun, especially given that none of the [example byte sources in the spec](https://streams.spec.whatwg.org/#example-rbs-push) do so. Yes, it really is. We'll need to update those to handle it properly. > Can we make this easier somehow? > * Automatically introspect `byobRequest.view` and if it's transferred, call (the equivalent of) `respondWithNewView(constructedView)` ... I don't think that's possible? If a buffer is transferred, we have no way to know *where it was transferred to*. We definitely cannot re-construct an `ArrayBuffer` around something that has been transferred. For all we know, that buffer is now being used by a different thread in a Web Worker. Until the underlying byte source actually calls `.respond()` or `.respondWithNewView()` itself, we have no way to "reclaim" the transferred buffer. > * ...and if it's not transferred, call `respond(0)`? That *might* work, but it can cause unexpected behavior: ```javascript const rs = new ReadableStream({ type: "bytes", pull(controller) { const byobRequest = controller.byobRequest; if (byobRequest) { // Note: we're not returning this promise, so the stream will not wait for it before canceling. fetchSomeBytes(byobRequest.view.byteLength).then((data) => { // If the stream is canceled while fetching the data, then the stream would have already "auto-responded" // to the BYOB request. This invalidates the request: its buffer is transferred back to the stream, // and its view is set to null. byobRequest.view.set(data, 0); // 💥 byobRequest.respond(data.byteLength); }); } } } ``` > * Relax the requirement that the last BYOB read should resolve with `value: emptyChunk`? This would break [the `readInto()` example](https://streams.spec.whatwg.org/#example-manual-read-bytes). The BYOB reader *needs* to get its buffer back. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/whatwg/streams/pull/1114#discussion_r604490796
Received on Tuesday, 30 March 2021 23:16:16 UTC