- From: Mattias Buelens <notifications@github.com>
- Date: Wed, 08 Jul 2020 13:51:11 -0700
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/pull/1053/review/445080016@github.com>
@MattiasBuelens requested changes on this pull request.
Looks pretty good! 🙂
From [your comment on #276](https://github.com/whatwg/streams/issues/276#issuecomment-648287943), I understand that we will not yet support the "double-transfer" case in this first version. Correct?
> There is no reference implementation of this functionality as jsdom does not support transferrable objects, and so it wouldn't be testable.
That is indeed unfortunate.
For [remote-web-streams](https://github.com/MattiasBuelens/remote-web-streams/), I wrote [a mock implementation of `MessageChannel`](https://github.com/MattiasBuelens/remote-web-streams/blob/5ca92e2aee8a0dfbc9bd60b88a524cd46e3fb130/test/mocks/MessageChannel.ts). It doesn't actually do any (de)serialization or send stuff between realms, it's just enough so I can run my tests. But I guess that wouldn't really work for a project like jsdom... 😅
> + 1. Let |type| be ? [$Get$](|data|, `"type"`).
+ 1. Let |value| be ? [$Get$](|data|, `"value"`).
+ 1. If ! [$Type$](|type|) is not String, return.
+ 1. If |type| is `"pull"`,
+ 1. If |backpressurePromise| is not undefined,
+ 1. [=Resolve=] |backpressurePromise| with undefined.
+ 1. Set |backpressurePromise| to undefined.
+ 1. Otherwise, if |type| is `"error"`,
+ 1. Perform ! [$WritableStreamDefaultControllerErrorIfNeeded$](|controller|, |value|).
+ 1. If |backpressurePromise| is not undefined,
+ 1. [=Resolve=] |backpressurePromise| with undefined.
+ 1. Set |backpressurePromise| to undefined.
+ 1. Add a handler for |port|'s {{MessagePort/messageerror}} event with the following steps:
+ 1. Let |error| be a new "{{DataCloneError}}" {{DOMException}}.
+ 1. Perform ! [$CrossRealmTransformSendError$](|port|, |error|).
+ 1. Perform ! [$WritableStreamDefaultControllerError$](|controller|).
```suggestion
1. Perform ! [$WritableStreamDefaultControllerError$](|controller|, |error|).
```
> + 1. Let |backpressurePromise| be [=a new promise=].
+ 1. Add a handler for |port|'s {{MessagePort/message}} event with the following steps:
+ 1. Let |data| be the data of the message.
+ 1. If ! [$Type$](|data|) is not Object, return.
+ 1. Let |type| be ? [$Get$](|data|, `"type"`).
+ 1. Let |value| be ? [$Get$](|data|, `"value"`).
+ 1. If ! [$Type$](|type|) is not String, return.
+ 1. If |type| is `"pull"`,
+ 1. If |backpressurePromise| is not undefined,
+ 1. [=Resolve=] |backpressurePromise| with undefined.
+ 1. Set |backpressurePromise| to undefined.
+ 1. Otherwise, if |type| is `"error"`,
+ 1. Perform ! [$WritableStreamDefaultControllerErrorIfNeeded$](|controller|, |value|).
+ 1. If |backpressurePromise| is not undefined,
+ 1. [=Resolve=] |backpressurePromise| with undefined.
+ 1. Set |backpressurePromise| to undefined.
```suggestion
1. Set |backpressurePromise| to undefined.
1. Disentangle |port|.
```
The readable's *cancelAlgorithm* disentangles its port when it sends the `"error"` message. Thus, the writable side should do the same when it receives that message.
> +
+<div algorithm>
+ <dfn abstract-op lt="SetUpCrossRealmTransformReadable">SetUpCrossRealmTransformReadable(|stream|,
+ |port|)</dfn> performs the following steps:
+
+ 1. Perform ! [$InitializeReadableStream$](|stream|).
+ 1. Let |controller| be a [=new=] {{ReadableStreamDefaultController}}.
+ 1. Let |backpressurePromise| be [=a new promise=].
+ 1. Add a handler for |port|'s {{MessagePort/message}} event with the following steps:
+ 1. Let |data| be the data of the message.
+ 1. If ! [$Type$](|data|) is not Object, return.
+ 1. Let |type| be ? [$Get$](|data|, `"type"`).
+ 1. Let |value| be ? [$Get$](|data|, `"value"`).
+ 1. If ! [$Type$](|type|) is not String, return.
+ 1. If |type| is `"chunk"`,
+ 1. If ! [$ReadableStreamDefaultControllerCanCloseOrEnqueue$](|controller|) is true,
Is this check still necessary after #1029?
> + 1. Set |backpressurePromise| to [=a new promise=].
+ 1. Otherwise, if |type| is `"close"`,
+ 1. Perform ! [$ReadableStreamDefaultControllerClose$](|controller|).
+ 1. Disentangle |port|.
+ 1. Otherwise, if |type| is `"error"`,
+ 1. Perform ! [$ReadableStreamDefaultControllerError$](|controller|, |value|)
+ 1. Disentangle |port|.
+ 1. Add a handler for |port|'s {{MessagePort/messageerror}} event with the following steps:
+ 1. Let |error| be a new "{{DataCloneError}}" {{DOMException}}.
+ 1. Perform ! [$CrossRealmTransformSendError$](|port|, |error|).
+ 1. Perform ! [$ReadableStreamDefaultControllerError$](|controller|, |error|).
+ 1. Disentangle |port|.
+ 1. Let |startAlgorithm| be an algorithm that returns undefined.
+ 1. Let |pullAlgorithm| be the following steps:
+ 1. Perform ! [$PackAndPostMessage$](|port|, `"pull"`, undefined).
+ 1. Return |backpressurePromise|.
In [remote-web-streams](https://github.com/MattiasBuelens/remote-web-streams/), I don't maintain a backpressure promise for `pull()`. [I return nothing](https://github.com/MattiasBuelens/remote-web-streams/blob/5ca92e2aee8a0dfbc9bd60b88a524cd46e3fb130/src/readable.ts#L25) (which gets interpreted as a promise resolved with `undefined`), and instead [I rely](https://github.com/MattiasBuelens/remote-web-streams/blob/5ca92e2aee8a0dfbc9bd60b88a524cd46e3fb130/src/readable.ts#L39-L40) on the fact that `ReadableStreamDefaultControllerEnqueue` will call `pull()` again if needed.
I can see that manually maintaining a backpressure promise makes it more obvious *when* the next pull can happen. On the other hand, it feels like we're duplicating some of the internal pull handling of `ReadableStream` here. For example, in `ReadableStreamTee`, we *do* return an immediately-resolved promise from its *pullAlgorithm*, and rely on the stream to not call pull again until we enqueue a chunk.
--
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/1053#pullrequestreview-445080016
Received on Wednesday, 8 July 2020 20:51:27 UTC