Re: [streams] Readable byte streams should support an internal queue (#353)

> My suggestion is having two separate classes.

I don't think this is the way to go. We should not have a class X whose internals are specified, based on interaction with a strategy, and class Y, whose internals are not specified but whose invariants are. Instead we should just have one class, X, which is flexible enough that any Y can be expressed by chosing a specific strategy. And, if you can come up with such a strategy, then of course you're free as an implementer to implement it without using strategies at all, as long as you behave exactly the same. But it's still just one class and one spec.

Maybe it would help if we added, somewhere prominent, a note like:

_Note for implementers: this spec describes stream classes controlled by underlying source or underlying sink JavaScript objects. This allows developers the flexibility to create streams with a wide variety of behaviors, while ensuring that their internal and external invariants are all maintained. Platform-created streams of these classes should behave as if they were also created from some conceivable JavaScript underlying source or sink object, in order to maintain those invariants. However, since such underlying source and sink objects are not externally visible once a stream has been constructed, an implementation is free to use any mechanism it wants to implement the resulting behavior; they don't literally need to create such objects._

> For BYOB read requests, the source just wants to get the view and fulfill the corresponding pending request with the view (possibly detached) filled with generated contents as-is.

I don't think this is necessarily true. For example if you were writing a source that was directly using `recv(2)`, this would not be good enough, because of kernel buffer overflow. You would want a queue to take care of these cases. In particular, you would want to use the `pull` -> `controller.respond()` flow in most cases, but if the kernel buffer is getting flow you would want to use `controller.enqueue()`.

*However,* I think it might be OK if we say that this is rare enough that we force authors (and implementers) to handle it on their own. That is, if we assume nobody will ever expose `read(2)` directly to JavaScript (see [my blog post](https://blog.domenic.me/reading-from-sockets/)), but instead will expose something that shields them from kernel buffer overflows, then maybe it is OK to not build in a queue.

But that means there will still be uneven flow, even for `getReader()`, which is kind of sad.

> I try to finish prototyping the ideas explained above. WIP branch is at https://github.com/whatwg/streams/blob/bytestream/index.bs.

Having typed all the above, I then went to skim your changes and I see that you actually implemented the queue! And allowing both types of readers to be used, with interop on both sides! Wow!! This is very convenient, if you are OK with it. Now I am a little confused :)

I will need to dig in to your branch more later to understand everything. (Now I know what you must feel like reviewing my big patch sets...)

---
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/issues/353#issuecomment-99912124

Received on Thursday, 7 May 2015 15:32:58 UTC