- From: Mattias Buelens <notifications@github.com>
- Date: Wed, 26 Jan 2022 15:36:41 -0800
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/pull/1208/review/864228136@github.com>
@MattiasBuelens commented on this pull request.
> @@ -475,6 +483,20 @@ function WritableStreamDefaultWriterGetDesiredSize(writer) {
return WritableStreamDefaultControllerGetDesiredSize(stream._controller);
}
+function WritableStreamDefaultWriterIsOrBecomesErrored(writer, errorListener) {
Here's two possible tests for this:
```javascript
promise_test(async t => {
const rs = recordingReadableStream();
const ws = recordingWritableStream();
const pipeToPromise = rs.pipeTo(ws);
await flushAsyncEvents();
rs.controller.error(error1);
ws.controller.error(error2);
await promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo must reject with readable\'s error');
assert_array_equals(rs.eventsWithoutPulls, []);
assert_array_equals(ws.events, []);
await promise_rejects_exactly(t, error1, rs.getReader().closed);
await promise_rejects_exactly(t, error2, ws.getWriter().closed);
}, 'Piping: error the readable stream right before erroring the writable stream');
promise_test(async t => {
const rs = recordingReadableStream();
const ws = recordingWritableStream();
const pipeToPromise = rs.pipeTo(ws);
await flushAsyncEvents();
ws.controller.error(error1);
rs.controller.error(error2);
await promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo must reject with writable\'s error');
assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
assert_array_equals(ws.events, []);
await promise_rejects_exactly(t, error1, ws.getWriter().closed);
await rs.getReader().closed;
}, 'Piping: error the writable stream right before erroring the readable stream');
```
The behavior might be a bit surprising though. In the first test, *ws* is still writable when we call `rs.controller.error()`, so we end up in:
https://github.com/whatwg/streams/blob/5afb0e014c08be94e49db7c0305aa211545e3add/reference-implementation/lib/abstract-ops/readable-streams.js#L294
This adds at least one microtask of delay (even if there are no pending writes), so we will *not yet* call `ws.abort(error1)`. Instead, `ws.controller.error(error2)` goes through, and the abort gets ignored later on.
However, in the second test, because *ws* immediately becomes errored, we *don't* wait for pending writes to complete and instead we *synchronously* call `rs.cancel(error1)`. Therefore, `rs.controller.error(error2)` gets ignored, and the stream ends up *cancelled* instead of *errored*.
---
The specification is a bit vague about this. It says:
> Wait until every chunk that has been read has been written (i.e. the corresponding promises have settled).
It doesn't say *how long* this step can take. We may want to require that if there are *no* pending writes (i.e. we've never started any writes, or all writes have already settled), then this step must complete *synchronously*. Then, in the first test, we *would* call `ws.abort(error1)` synchronously and prevent `ws.controller.error(error2)`. However, that might be tricky to actually implement correctly... 🤔
--
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/pull/1208#discussion_r793139011
You are receiving this because you are subscribed to this thread.
Message ID: <whatwg/streams/pull/1208/review/864228136@github.com>
Received on Wednesday, 26 January 2022 23:36:53 UTC