Skip to content

stream: Duplex autoDestroy with disabled readable/writable

stream.Duplex and net.Socket slightly differs in behavior.

Especially when it comes to the case where one side never becomes readable or writable. This aligns Duplex with the behavior of Socket.

The "trick" net.Socket does is to explicitly set writable/readable to false instead of calling end()/push(null) to avoid the 'finish'/'end' events.

This PR extract the streams part of https://github.com/nodejs/node/pull/31806 for easier review.

---- EDIT UPDATED DESCRIPTION ----

Some streams are implemented as Duplex but don't know whether they are unidirectional or not until runtime. In the case that it is determined as unidirectional then one of the sides need to be disabled for e.g. autoDestroy, stream.finished to work properly. However, it doesn't make sense to call end()/push(null) since it never were writable/readable and emitting 'finish'/'close' is weird/confusing.

They way e.g. net.Socket resolves it (and maybe quic and other implementors might want to resolve it? @jasnell) is to explicitly set writable/readable to false once/if it has determined the stream to be unidirectional. This works already, however it would break autoDestroy which (before this PR) waits for both sides to complete, when (in this case) only one is expected complete.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

Merge request reports

Loading