Re: [streams] Support reading bytes into buffers allocated by user code on platforms where only async read is available (#253)

> One concern about (C) is that people may be impressed that calling multiple pull()s is harmless when using object streams, and may call many pull()s without being aware of internal allocation of ArrayBuffer and kicking read. Naming it pull() than wait() gives some notion of side-effect, but still weak?
> So, I think (C) requires that for pull(undefined) something similar to auto mode happens. Even if many many pull(undefined) calls are made, we keep (the total amount of outstanding I/O requests) + (total size of filled but not yet read()-ed buffers) under some high water mark.

It's a good idea.

--

I'm trying to describe pull()'s abstract behavior (for option (C) + always manual RBS).

- A stream can request a data chunk to the underlying source at any timing when it is not closed or errored.
- A stream must request a data chunk to the underlying source when pull() is called and the following conditions are met.
  - There is no pending data request.
  - The stream's state is "waiting"
- pull() returns a fulfilled promise when the stream is closed or errored.
- pull() returns a promise which will be fulfilled when a certain data request is done, the stream gets closed or it gets errored. The pull() call is said to be **associated** with the data request.
  - The associated data request must satisfy one of the following (before associated):
    - It is the first pending data request not associated with any pull() call.
    - It is the last pending data request associated with one or more pull() calls all of which are called on the stream.
- Once a data request is associated with a pull() call, the data chunk will be delivered to the reader on which the pull was called, even when the reader is not active.

Notes:
- These rules describe only user-facing behaviors. "requesting a data chunk to the underlying source" doesn't mean that an actual function call is immediately made. @tyoshino's [request freezing idea] (https://github.com/whatwg/streams/issues/253#issuecomment-77330772) is completely valid in this setting.
- It is guaranteed that stream's state is not waiting when a promise returned by a pull() is fulfilled.
- A stream may associate one data request for each pull() call. In such a case, each chunk arrival resolves one promise returned by pull(). (e.g. ReadableByteStream)
- A stream may associate multiple pull calls for one data request. In such a case, one chunk arrival may resolve multiple promises returned by pull(). (e.g. ReadableStream)
- A stream may become readable without fulfilling __all__ pending promises returned by multiple pull calls.
- These rules intentionally don't include queue and backpressure, because in my opinion they are ReadableStream specific.

I think these rules define the user-facing pull() behavior. They cover ReadableStream and ReadableByteStream (and hopefully other custom streams).

I know they are a bit complicated. Simpler rules are wanted...

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

Received on Thursday, 5 March 2015 16:29:13 UTC