- From: Mattias Buelens <notifications@github.com>
- Date: Sat, 30 Oct 2021 11:01:31 -0700
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/issues/1124/955570502@github.com>
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