Skip to content

Commit

Permalink
Put design rationales of ReadableByteStream
Browse files Browse the repository at this point in the history
Issue: whatwg#177
  • Loading branch information
tyoshino committed Oct 2, 2014
1 parent c8f8622 commit 81104fe
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions BinaryExtension.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@

## Readable Byte Stream API

This extended API allows efficient access to a data source available for read via the POSIX non-blocking `read(2)` API or similar.

We map the non-blocking `read(2)` to a non-blocking method `ReadableByteStream.prototype.readInto()`, and asynchronous notification of I/O events to the state and Promises.

`ReadableByteStream` has the same states as the `ReadableStream`. State transition happens on `notifyReady()` call and on calling `readInto()` of the underlying source.

When a `ReadableByteStream` is constructed, the underlying source watches for events on the file descriptor from which data is read using some I/O event loop built with `select(2)`, `poll(2)`, etc. `ReadableByteStream` provides a function `notifyReady()` to the underlying source. It is intended to be called when the file descriptor is ready. It moves the stream into the `"readable"` state. The `"readable"` state doesn't necessarily mean some bytes are available for read. It just means that `ReadableByteStream.prototype.readInto()` can be called. We need to call `read(2)` to know what kind of event has actually happened (new data available for read or the EOF or an error), so we enter `"readable"` and let the user call `readInto()`.

`ReadableByteStream`'s constructor takes `readInto()` function from the underlying source instead of taking `pull()` and providing `[[enqueue]]`. A user calls `ReadableByteStream.prototype.readInto()` with an ArrayBuffer prepared by the user to get available data written into the ArrayBuffer. The method calls the `readInto()` of the underlying source with the ArrayBuffer. `readInto()` calls `read(2)` to write read data directly onto the ArrayBuffer. The stream translates the return value of the function into the next state of the stream and returns the number of bytes written to the given ArrayBuffer as follows:

- If there are bytes available for read,
- The underlying source's `readInto()` should write the bytes into the ArrayBuffer and return the number of bytes written.
- Then, the stream stays in the `"readable"` state and `stream.readInto()` will return the number of bytes written.
- If the file descriptor has nothing available for non-blocking read, e.g. `read(2)` returning `EAGAIN`, `EWOULDBLOCK`, etc.,
- The underlying source's `readInto()` should write nothing into the ArrayBuffer and return -2.
- Then, the stream enters the `"waiting"` state and `stream.readInto()` will return 0.
- If the file descriptor reached the EOF,
- The underlying source's `readInto()` should write nothing into the ArrayBuffer and return -1.
- Then, the stream enters the `"closed"` state and `stream.readInto()` will return 0.
- If the `read(2)` fails,
- The underlying source's `readInto()` should write nothing into the ArrayBuffer and throw.
- Then, the stream enters the `"errored"` state and `stream.readInto()` will return 0.

By admitting returning the ArrayBuffer with no data written on it, `ReadableByteStream` satisfies the semantics of `ReadableStream`.

### ReadableByteStream

```
Expand Down

0 comments on commit 81104fe

Please sign in to comment.