- From: Mattias Buelens <notifications@github.com>
- Date: Thu, 20 Jan 2022 13:34:25 -0800
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/issues/1207/1017947644@github.com>
Thinking about it some more, I don't think that will work. I think I got a bit confused when I wrote my previous reply. 😬 The problem is not that we *start* a new read after the destination has become errored. We're already awaiting `writer.ready` which is always rejected *immediately* in [step 8 of WritableStreamStartErroring](https://streams.spec.whatwg.org/commit-snapshots/908ceddfb813ec0d9c727393edfb13d810e694f1/#writable-stream-start-erroring). It *might* be possible that the destination becomes errored *during the same microtask* that `writer.ready` becomes resolved, so a synchronous check may still be appropriate. The real problem is when there's *already* a pending read, and *then* the destination becomes errored at the same time that a chunk is enqueued onto the source. So: ```javascript writableController.error("💥"); readableController.enqueue("a"); ``` Erroring the writable will *asynchronously* reject `writer.closed`, but enqueuing a chunk will *synchronously* call the read request's chunk steps. Even if we added a synchronous check [here](https://github.com/whatwg/streams/blob/908ceddfb813ec0d9c727393edfb13d810e694f1/reference-implementation/lib/abstract-ops/readable-streams.js#L204-L217): ```javascript ReadableStreamDefaultReaderRead( reader, { chunkSteps: chunk => { if (dest._state !== 'writable') { // ...now what? 🤷♂️ } currentWrite = transformPromiseWith( WritableStreamDefaultWriterWrite(writer, chunk), undefined, () => {} ); resolveRead(false); }, closeSteps: () => resolveRead(true), errorSteps: rejectRead } ); ``` ...we would still be unable to do anything useful with `chunk`. Ideally, we'd put it back *at the start* of the source's queue, but we don't have a way to do that. The only way we can avoid this is if we can *synchronously* release the reader as soon as the destination becomes errored, i.e. attach an error callback to the writer. (Note that doing `enqueue()` followed by `error()` *can* result in the newly enqueued chunk being successfully written to the destination *before* the destination becomes errored. The read request's chunk steps synchronously call `writer.write()`, which can synchronously call `sink.write()` and complete the write. So we don't "accidentally" drop a chunk in this case.) -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/streams/issues/1207#issuecomment-1017947644 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/streams/issues/1207/1017947644@github.com>
Received on Thursday, 20 January 2022 21:34:38 UTC