- 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