Re: [whatwg/streams] can streams be transferred via postMessage()? (#276)

> But yea! The solution you mention is kinda what I'm doing right now. I'm creating a MessageChannel and passing the stream throught it instead to get a more direct A to B destination.
> 
> Is that what you must do?

That's a good workaround to avoid triggering the bug, but ideally Chrome fixes the bug so the more natural solution of re-transferring the `ReadableStream` "just works".

> Is it intendent to closes both sides?

If a worker terminates, it's expected that all `MessagePort`s that are owned by the worker are closed. But in your scenario, the worker *should no longer own* any (internal) `MessagePort`s attached to the transferred stream.

> Is that something that might change for allowing it to happen? should it "un-pipe" when re-transferring? or simply put it "re-use the internal `MessagePort`"

I'm not an expert, but it seems reasonable that Chrome's implementation could "remember" that a `ReadableStream` instance was deserialized from an internal `MessagePort`. When such a `ReadableStream` is transferred *again*, instead of setting up a new `MessageChannel` to transfer chunks, Chrome could re-use the existing `MessagePort` instead.

I don't think an explicit "un-pipe" operation is necessary. The [deserialization](https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/streams/CommonOperations.js?l=532&rcl=fff5f8e61ff8c7b07a72d6e275b3c4773ef9c4fe) works by listening for `message` events on the `MessagePort` (to enqueue or close the stream) and sending control messages (for pulling and cancelling the stream) using `postMessage`. When the port is transferred, that listener will no longer be fired, since all pending and future `message` events will be transferred. I *think* pull and cancel can't happen after the stream is already transferred, so the code shouldn't ever try to call `postMessage` on a transferred port...?

The only thing [serialization](https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/streams/ReadableStream.js?l=1048&rcl=fff5f8e61ff8c7b07a72d6e275b3c4773ef9c4fe) would have to do is lock the stream. Normally, this would happen automatically because of the pipe to the "cross-realm transform writable". Such a pipe is not necessary here, since a similar pipe for that port is already running in another realm where the readable stream was initially transferred. The browser can just lock the stream in the current realm, and transfer the existing port over to another realm.

-- 
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/issues/276#issuecomment-483018862

Received on Sunday, 14 April 2019 17:07:24 UTC