- From: Mattias Buelens <notifications@github.com>
- Date: Thu, 25 Mar 2021 16:43:15 -0700
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/pull/1114/review/621662098@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); > I kind of thought the stream machinery handled the case of returning the buffers when closed for us? No, it doesn't. If you look at [ReadableStreamClose](https://streams.spec.whatwg.org/commit-snapshots/dd76a17a3738d78708a8dfd8f0508e717d6a1988/#readable-stream-close), it only runs the close steps of read requests from a *default reader*. It doesn't run any close steps of read-into requests from a *BYOB reader*. And that's because *it cannot*. In order to run those close steps, it must construct a _chunk_ with a transferred version of the original read-into request's buffer. But it doesn't *have* that buffer, since the underlying byte source might have transferred it from `byobRequest.view` to some other API to do the reading. (For example, by passing it to another `byobReader.read(view)` call like in `ReadableByteStreamTee`.) We can only call these close steps when we have received control back of that buffer, which must happen through either `byobRequest.respond()` (if the byte source didn't transfer it and instead wrote directly into the buffer) or `.respondWithNewView()` (if it did transfer it). This also means that *every underlying byte source implementation* must do something like this in its `cancel` algorithm: ```javascript new ReadableStream({ type: 'bytes', start(controller) { this._controller = controller; }, pull(controller) { // call controller.enqueue() or controller.byobRequest.respond() somehow... }, cancel() { // finish any pending BYOB request (even if we never used it ourselves) this._controller.byobRequest?.respond(0); } }); ``` Otherwise, the last BYOB read can never resolve to `{ value: emptyChunk, done: true }` after canceling the stream. -- 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_r601907474
Received on Thursday, 25 March 2021 23:43:28 UTC