Re: [whatwg/streams] Setting Object.prototype.then permits interfering with pipeTo() internals (#933)

> This would also be inconsistent with all other iter-result objects on the platform, which makes me uncomfortable.

Me too. Concretely, `hasOwnProperty` seems to be the worst problem. I don't have a good feeling for how bad it is in practice.

When I was playing for this I found that `"" + result` throws, which is fun, but probably not critically important.

I generally prefer the null prototype as it removes a surprising footgun that could trip up other standards  looking to embed streams. But we could alternatively add warnings to the standard text for ReadableStreamDefaultReaderRead() and other operations which appear to resolve to an iterator, but which can in fact resolve to undefined or anything else. And standards such as fetch that call those operations would need to write tests for those cases.

> We explicitly use operations like ReadableStreamCancel

I'd forgotten about that part. Adding a flag will work but it's very hacky.

> Maybe it'd be worth thinking about what a simpler/more optimized pipeTo() implementation would be and coding that more directly into the standard? For example, not creating promises that are never seen or are consumed only by spec code.

Simple sketch:
1. ReadableStream gets a new boolean slot, [[pipeToIsWaitingForSomething]].
2. When controller.enqueue() or close() or error() are called, if [[pipeToIsWaitingForSomething]] is **true**, a new abstract operation ReadableStreamSomethingHappened() is called.
3. A new internal method [[PopQueue]] on the controllers is called where [[PullSteps]] is called now. It returns a Record {[[value]]: value} or undefined depending on whether there is something in the queue.
4. When [[PopQueue]] returns undefined, pipeTo() sets [[pipeToIsWaitingForSomething]].
5. Logic mostly equivalent to ReadableStreamDefaultReaderRead, but which calls [[PopQueue]], is included in the pipeTo() algorithm.
6. ReadableStreamSomethingHappened() sets [[pipeToIsWaitingForSomething]] to **false**. During the normal read/write phase it then runs the ReadableStreamDefaultReaderRead-like algorithm.

This is already more prescriptive than the definition of pipeTo(). I think the biggest difference is that it removes the flexibility to run an arbitrary number of microtasks between enqueue() and write(). I think it makes the existing reference implementation non-conformant.

-- 
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/933#issuecomment-400568004

Received on Wednesday, 27 June 2018 07:16:29 UTC