stream-to-it icon indicating copy to clipboard operation
stream-to-it copied to clipboard

Add option not to destroy duplex stream when either the source or sink iterable completes

Open gnarea opened this issue 3 years ago • 0 comments

(First of all, stream-to-it and it-pipe are amongst my favourite NPM packages: My code would've been really complicated had you not made these packages available, so thank you so much!)

I'm implementing a WebSocket-based protocol using ws. ws offers a duplex stream to communicate with the peer and I'm wrapping that stream in a "duplex iterable" (generated by duplex()), which I pass to it-pipe.

The code mostly works as expected, but I'm running into two related issues:

  • If there's a break in the loop, Node.js would call duplex.destroy(), which will cause ws to close the connection abruptly.
  • If the duplex' sink completes normally, Node.js would call duplex.end(), which will cause ws to close the connection normally -- Even if we're waiting for messages from the source. For example, the protocol I'm implementing sends messages that must be acknowledged by the peer, so if we're done sending messages we should still keep the connection open to receive outstanding ACKs.

I think both issues could be solved if duplex() supported an option that wouldn't call destroy()/end() on the underlying stream (maybe as a pass-through stream). That'd allow me to do something like this on the server:

const wsDuplex = WebSocket.createWebSocketStream(ws);
try {
  await pipe(loadMessages, duplex(wsDuplex, {allowClosing: false}), processAcknowledgements)

  // If we get to this point, processAcknowledgements() must've ended the loop
  ws.close(1000, 'All good')
} catch (err) {
  ws.close(1008, 'Something went wrong')
}

(duplex.end() will still be called when the connection is closed. OTOH, the example above is overly simplified: I'd probably have to use an AbortableController to signal the source of the duplex iterable when the client closes the connection.)

Thoughts?

gnarea avatar Oct 21 '20 22:10 gnarea