- From: Adam Rice <notifications@github.com>
- Date: Wed, 12 Dec 2018 23:41:52 -0800
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/issues/976@github.com>
**Principle:** cloning a stream should be a no-op (except that queue size increases by one chunk). # Cloning formulas "Cloning" is an operation which locks the original stream and constructs a new stream that behaves just like it. It is a useful building block for stream manipulations and it is also used in the construction of transferable streams. ## Cloning a readable ```javascript const rs2 = rs1.pipeThrough(new TransformStream()); ``` ## Cloning a writable ```javascript const internalTS = new TransformStream(); internalTS.readable.pipeTo(ws1); ws2 = internalTS.writable; ``` # Problem The cloned readable stream `rs2` preserves the properties of the original stream `rs1`. However, the cloned writable stream `ws2` loses information. If you do `readable.pipeTo(ws1)` then the promise returned by `pipeTo()` will not resolve until `underlyingSink.close()` has resolved. However, if you do `readable.pipeTo(ws2)`, `pipeTo()` will resolve as soon as `readable` is closed. This problem was identified while working on the tests for transferable streams. # Cause An underlying source is not notified when downstream has finished consuming the data. Once the ReadableStream is closed, it gets no further notification about the state of the pipe. `pipeTo()` waits for all writes to complete by design, but this is independent of the readable stream's main state machine. # Proposed fix ReadableStream's underlyingSource will gain an additional method, `finally()`, which is called once the stream is completely quiescent, ie. after it is `CLOSED` or `ERRORED` and no operations are pending. See https://github.com/whatwg/streams/issues/636 for background and other use cases for the `finally()` method. There will be a new abstract operation, `ReadableStreamMakeFinallyWaitFor(promise)` which will delay the call to `finally()` until the passed-in promise is settled. This new operation could in principle be exposed on the `ReadableStreamDefaultReader` object, but isn't because of its limited utility. Instead, we keep it as an internal abstract operation for now, only used by the pipeTo implementation. The `finally()` method will be passed a TBD argument indicating whether the ReadableStream closed without error. If the promise passed to `ReadableStreamMakeFinallyWaitFor` is rejected, then this argument will indicate an error occurred. `CreateReadableStream()` will gain an extra operation argument corresponding to the `finally()` method. This will be used by the TransformStream implementation to control the timing of changing the state of the writable side to `CLOSED` or `ERRORED`, which in turn will change the timing of when a pipe to the writable side completes. The new effect is that a pipe to `ws2` will close no sooner than `close()` or `abort()` on `ws1`'s underylingSink complete. -- 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/976
Received on Thursday, 13 December 2018 07:42:14 UTC