- 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