Skip to content

Commit a6592e6

Browse files
kovanclaude
andcommitted
doc: clarify readable._read() and pipe() error behavior
- Rewrite readable._read() description to resolve contradictory statements about when _read() is called relative to push(). The new text clarifies that: push() may be called multiple times until it returns false; _read() will not be called again until push() provides non-empty data; and if data is not immediately available, push() should be called asynchronously when data arrives. - Clarify pipe() error caveat to specify that when the source stream is destroyed or emits an error, the destination is not closed automatically. Recommend stream.pipeline() for automatic cleanup. Verified against source: - lib/internal/streams/readable.js: kReading flag set before _read(), cleared in push(); maybeReadMore_ loops while kReading is unset - pipe() only listens for 'error' on destination, not on source Fixes: #42291 Fixes: #45072 Fixes: #46908 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9ff27fd commit a6592e6

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

doc/api/stream.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,10 +1539,12 @@ reader.on('end', () => {
15391539
});
15401540
```
15411541

1542-
One important caveat is that if the `Readable` stream emits an error during
1543-
processing, the `Writable` destination _is not closed_ automatically. If an
1544-
error occurs, it will be necessary to _manually_ close each stream in order
1545-
to prevent memory leaks.
1542+
One important caveat is that if the `Readable` stream is destroyed or emits an
1543+
error during processing, the `Writable` destination _is not closed_
1544+
automatically. It will be necessary to _manually_ close each stream in order
1545+
to prevent memory leaks. The [`stream.pipeline()`][] method should be used
1546+
instead when automatic cleanup of all streams on error or completion is
1547+
desired.
15461548

15471549
The [`process.stderr`][] and [`process.stdout`][] `Writable` streams are never
15481550
closed until the Node.js process exits, regardless of the specified options.
@@ -4228,19 +4230,19 @@ methods only.
42284230
All `Readable` stream implementations must provide an implementation of the
42294231
[`readable._read()`][] method to fetch data from the underlying resource.
42304232
4231-
When [`readable._read()`][] is called, if data is available from the resource,
4232-
the implementation should begin pushing that data into the read queue using the
4233-
[`this.push(dataChunk)`][stream-push] method. `_read()` will be called again
4234-
after each call to [`this.push(dataChunk)`][stream-push] once the stream is
4235-
ready to accept more data. `_read()` may continue reading from the resource and
4236-
pushing data until `readable.push()` returns `false`. Only when `_read()` is
4237-
called again after it has stopped should it resume pushing additional data into
4238-
the queue.
4239-
4240-
Once the [`readable._read()`][] method has been called, it will not be called
4241-
again until more data is pushed through the [`readable.push()`][stream-push]
4242-
method. Empty data such as empty buffers and strings will not cause
4243-
[`readable._read()`][] to be called.
4233+
When [`readable._read()`][] is called, the implementation should push data
4234+
into the read queue using [`this.push(dataChunk)`][stream-push]. This can be
4235+
done synchronously or asynchronously. The implementation may call
4236+
[`this.push()`][stream-push] multiple times to supply data, but should stop
4237+
when [`readable.push()`][stream-push] returns `false`, which indicates the
4238+
internal buffer has reached the `highWaterMark`. Once the implementation stops
4239+
pushing, it should only resume when [`readable._read()`][] is called again.
4240+
4241+
If data is not immediately available from the underlying resource, the
4242+
implementation should call [`this.push()`][stream-push] later, when data
4243+
becomes available. [`readable._read()`][] will not be called again until
4244+
[`readable.push()`][stream-push] is called with non-empty data (a non-empty
4245+
{Buffer}, non-empty {string}, or any value in object mode).
42444246
42454247
The `size` argument is advisory. For implementations where a "read" is a
42464248
single operation that returns data can use the `size` argument to determine how

0 commit comments

Comments
 (0)