| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ec226a2 commit 238466b
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -443,9 +443,46 @@ first argument. To reliably detect write errors, add a listener for the | |||
| 443 | 443 | The return value is `true` if the internal buffer does not exceed | |
| 444 | 444 | `highWaterMark` configured when the stream was created after admitting `chunk`. | |
| 445 | 445 | If `false` is returned, further attempts to write data to the stream should | |
| 446 | - stop until the [`'drain'`][] event is emitted. However, the `false` return | ||
| 447 | - value is only advisory and the writable stream will unconditionally accept and | ||
| 448 | - buffer `chunk` even if it has not not been allowed to drain. | ||
| 446 | + stop until the [`'drain'`][] event is emitted. | ||
| 447 | + | ||
| 448 | + While a stream is not draining, calls to `write()` will buffer `chunk`, and | ||
| 449 | + return false. Once all currently buffered chunks are drained (accepted for | ||
| 450 | + delivery by the operating system), the `'drain'` event will be emitted. | ||
| 451 | + It is recommended that once write() returns false, no more chunks be written | ||
| 452 | + until the `'drain'` event is emitted. While calling `write()` on a stream that | ||
| 453 | + is not draining is allowed, Node.js will buffer all written chunks until | ||
| 454 | + maximum memory usage occurs, at which point it will abort unconditionally. | ||
| 455 | + Even before it aborts, high memory usage will cause poor garbage collector | ||
| 456 | + performance and high RSS (which is not typically released back to the system, | ||
| 457 | + even after the memory is no longer required). Since TCP sockets may never | ||
| 458 | + drain if the remote peer does not read the data, writing a socket that is | ||
| 459 | + not draining may lead to a remotely exploitable vulnerability. | ||
| 460 | + | ||
| 461 | + Writing data while the stream is not draining is particularly | ||
| 462 | + problematic for a [Transform][], because the `Transform` streams are paused | ||
| 463 | + by default until they are piped or an `'data'` or `'readable'` event handler | ||
| 464 | + is added. | ||
| 465 | + | ||
| 466 | + If the data to be written can be generated or fetched on demand, it is | ||
| 467 | + recommended to encapsulate the logic into a [Readable][] and use | ||
| 468 | + [`stream.pipe()`][]. However, if calling `write()` is preferred, it is | ||
| 469 | + possible to respect backpressure and avoid memory issues using the | ||
| 470 | + the [`'drain'`][] event: | ||
| 471 | + | ||
| 472 | + ```js | ||
| 473 | + function write (data, cb) { | ||
| 474 | + if (!stream.write(data)) { | ||
| 475 | + stream.once('drain', cb) | ||
| 476 | + } else { | ||
| 477 | + process.nextTick(cb) | ||
| 478 | + } | ||
| 479 | + } | ||
| 480 | + | ||
| 481 | + // Wait for cb to be called before doing any other write. | ||
| 482 | + write('hello', () => { | ||
| 483 | + console.log('write completed, do more writes now') | ||
| 484 | + }) | ||
| 485 | + ``` | ||
| 449 | 486 | ||
| 450 | 487 | A Writable stream in object mode will always ignore the `encoding` argument. | |
| 451 | 488 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments