@@ -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
0 commit comments