Skip to content

Commit 04f1b72

Browse files
jasnellnodejs-github-bot
authored andcommitted
stream: correct strict pending-write behavior & cancellation
Signed-off-by: James M Snell <jasnell@gmail.com> Assisted-by: Opencode PR-URL: #66079 Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
1 parent 0d4a844 commit 04f1b72

5 files changed

Lines changed: 784 additions & 200 deletions

File tree

‎doc/api/stream_iter.md‎

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,8 +1583,9 @@ added:
15831583

15841584
> Stability: 1 - Experimental
15851585
1586-
* `readable` {stream.Readable|Object} A classic Readable stream or any object
1587-
with `read()`, `on()`, and `off()` methods.
1586+
* `readable` {stream.Readable|Object} A classic Readable stream or a compatible
1587+
object with `read()`, `pipe()`, `destroy()`, `on()`, and `removeListener()`
1588+
methods.
15881589
* Returns: {AsyncIterable} whose chunks fulfill with {Uint8Array\[]}
15891590

15901591
Converts a classic Readable stream (or duck-typed equivalent) into a
@@ -1593,8 +1594,8 @@ stream/iter async iterable source that can be passed to [`from()`][],
15931594

15941595
If the object implements the [`toAsyncStreamable`][] protocol (as
15951596
`stream.Readable` does), that protocol is used. Otherwise, the function
1596-
duck-types on `read()`, `on()`, and `off()` (EventEmitter) and wraps the
1597-
stream with a batched async iterator.
1597+
duck-types on `read()`, `pipe()`, `destroy()`, `on()`, and `removeListener()`
1598+
(EventEmitter) and wraps the stream with a batched async iterator.
15981599

15991600
The result is cached per instance -- calling `fromReadable()` twice with the
16001601
same stream returns the same iterable.
@@ -1639,13 +1640,14 @@ added:
16391640

16401641
> Stability: 1 - Experimental
16411642
1642-
* `writable` {stream.Writable|Object} A classic Writable stream or any object
1643-
with `write()` and `on()` methods.
1643+
* `writable` {stream.Writable|Object} A classic Writable stream or a compatible
1644+
object with `write()`, `end()`, `destroy()`, `on()`, and `removeListener()`
1645+
methods.
16441646
* `options` {Object}
16451647
* `backpressure` {string} Backpressure policy. **Default:** `'strict'`.
1646-
* `'strict'` -- writes are rejected when the buffer is full. Catches
1647-
callers that ignore backpressure.
1648-
* `'unbounded'` -- writes wait for drain when the buffer is full. Recommended
1648+
* `'strict'` -- one write may wait while the buffer is full. Further writes
1649+
are rejected until it is accepted or canceled.
1650+
* `'unbounded'` -- writes are queued while the buffer is full. Recommended
16491651
for use with [`pipeTo()`][].
16501652
* `'drop-newest'` -- writes are silently discarded when the buffer is full.
16511653
* `'drop-oldest'` -- **not supported**. Throws `ERR_INVALID_ARG_VALUE`.
@@ -1657,8 +1659,9 @@ destination.
16571659

16581660
Since all writes on a classic Writable are fundamentally asynchronous,
16591661
the synchronous Writer methods (`writeSync`, `writevSync`, `endSync`) always
1660-
return `false` or `-1`, deferring to the async path. The per-write
1661-
`options.signal` parameter from the Writer interface is also ignored.
1662+
return `false` or `-1`, deferring to the async path. A queued `write()` or
1663+
`writev()` can be canceled with its `options.signal` before it reaches the
1664+
classic Writable.
16621665

16631666
If `writer.fail(reason)` receives a non-Error reason, the classic Writable is
16641667
destroyed with an `ERR_FALSY_VALUE_REJECTION` or `ERR_OPERATION_FAILED` error.
@@ -1817,6 +1820,10 @@ non-Error reason is wrapped in an `ERR_FALSY_VALUE_REJECTION` or
18171820
`ERR_OPERATION_FAILED` error before it is passed to the callback. The error's
18181821
`reason` property contains the original value.
18191822

1823+
Destroying the Writable before successful completion calls `writer.fail()`.
1824+
If `fail()` is unavailable, `Symbol.dispose` or `Symbol.asyncDispose` is used
1825+
when implemented by the Writer.
1826+
18201827
The Writable uses the default classic stream `highWaterMark`. Classic stream
18211828
backpressure bounds writes waiting to reach the underlying Writer, while the
18221829
Writer controls completion of the active `_write()` or `_writev()` operation.

0 commit comments

Comments
 (0)