Re: [whatwg/streams] Permitting transferable stream optimisation (#1124)

We could model a "native stream" as being a `ReadableStream` created in a separate realm, and immediately transferring it to the current realm. That way, we already have a "cross-realm transform readable" within the current realm, so we can transfer it again without worrying about whether the current realm will stay alive. Of course, this assumes we fix #1063 first... ๐Ÿ˜… 

Something along the lines of:
1. Let _nativeReadable_ be a new `ReadableStream` in some (user-agent specific) Realm.
1. Set up _nativeReadable_ given _pullAlgorithm_ "inside that other Realm".
1. Let _serialized_ be ! StructuredSerializeWithTransfer(_nativeReadable_, [_nativeReadable_]) "inside that other Realm".
1. Let _readable_ be ! StructuredDeserializeWithTransfer(_serialized_, the current Realm).
1. Return _readable_.

This is still a bit vague though: we have to synchronously run some steps inside a different realm, and get the results in the current realm. That's because all of the internal promises from the _pullAlgorithm_, plus the pipe created by `ReadableStream`'s transfer steps must be able to outlive the current realm.

We could make this more explicit by creating the cross-realm transform streams directly, rather than using the transfer and transfer receiving steps. This requires a bunch more extra ceremony, though:
1. Let _port1_ be a new `MessagePort` in the current Realm.
1. Let _port2_ be a new `MessagePort` in the current Realm.
1. Entangle _port1_ and _port2_.
1. Let _readable_ be a new `ReadableStream` in the current Realm.
1. Perform ! SetUpCrossRealmTransformReadable(_readable_, _port1_).
    * This is similar to `ReadableStream`'s transfer-receiving steps. Yes, I know, we're doing things the wrong way around. ๐Ÿ˜› 
1. Let _serializedRecord_ be StructuredSerializeWithTransfer(_port2_, ยซ _port2_ ยป).
1. Run these steps in parallel "in some other Realm":
    1. Let _deserializedRecord_ be ! StructuredDeserializeWithTransfer(_serializedRecord_, the current Realm).
    1. Let _port_ be _deserializedRecord_.\[[Deserialized]].
    1. Let _writable_ be a new `WritableStream` in the current Realm.
    1. Perform ! SetUpCrossRealmTransformWritable(_writable_, _port_).
        * This is similar to `ReadableStream`'s transfer steps.
    1. Let _nativeReadable_ be a new `ReadableStream` in the current Realm.
    1. Set up _nativeReadable_ given _pullAlgorithm_.
    1. Let _promise_ be ! ReadableStreamPipeTo(_nativeReadable_, _writable_, false, false, false).
    1. Set _promise_.\[[PromiseIsHandled]] to true.
        * Because we set up the pipe inside *the other Realm*, it'll still work even if *the current Realm* destroyed.
1. Return _readable_.

The disadvantage with this approach is that these native streams must always live in *some other realm*, even if they are never transferred and only used from the current realm. This might defeat the benefits of the optimization... ๐Ÿ˜ฌ 

-- 
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/1124#issuecomment-955570502

Received on Saturday, 30 October 2021 18:01:44 UTC