New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http2: support generic `Duplex` streams #16269

Closed
wants to merge 4 commits into
base: master
from

Conversation

Projects
None yet
6 participants
@addaleax
Member

addaleax commented Oct 17, 2017

Commits:

  • src: allow top-level calls into JSStream
    Allow JSStream instances to be used more flexibly by explicitly
    enabling calls that have no JS stack below them.

  • src: turn JS stream into a full duplex
    Remove unused methods for reading data from JSStream and add
    those required for emitting data or an EOF event to the JS side,
    in essentially the same way that LibuvStreamWrap does it.

  • http2: support generic Duplex streams
    Support generic Duplex streams through using StreamWrap
    on the server and client sides, and adding a createConnection
    method option similar to what the HTTP/1 API provides.

    Since HTTP2 is, as a protocol, independent of its underlying transport
    layer, Node.js should not enforce any restrictions on what streams
    its internals may use.

Ref: #16256

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
Affected core subsystem(s)

http2

@addaleax

This comment has been minimized.

Show comment
Hide comment
Member

addaleax commented Oct 17, 2017

default:
throw new errors.Error('ERR_HTTP2_UNSUPPORTED_PROTOCOL', protocol);
if (typeof options.createConnection === 'function') {
socket = options.createConnection(authority, options);

This comment has been minimized.

@jasnell

jasnell Oct 17, 2017

Member

should likely type check the return value

@jasnell

jasnell Oct 17, 2017

Member

should likely type check the return value

This comment has been minimized.

@addaleax

addaleax Oct 18, 2017

Member

I think all we could do here is doing some duck-type checking, e.g. verifying that .write() and .on() are present…

@addaleax

addaleax Oct 18, 2017

Member

I think all we could do here is doing some duck-type checking, e.g. verifying that .write() and .on() are present…

This comment has been minimized.

@apapirovski

apapirovski Oct 20, 2017

Member

Do we really need to? This is very much opt-in... What does http do for createConnection?

@apapirovski

apapirovski Oct 20, 2017

Member

Do we really need to? This is very much opt-in... What does http do for createConnection?

This comment has been minimized.

@addaleax

addaleax Oct 20, 2017

Member

It doesn’t do any explicit typechecking either, yes.

@addaleax

addaleax Oct 20, 2017

Member

It doesn’t do any explicit typechecking either, yes.

This comment has been minimized.

@jasnell

jasnell Oct 20, 2017

Member

Ok. I won't block on that. I much prefer the APIs to be stricter here and not gate based on what we do in http1 but I can live with this.

@jasnell

jasnell Oct 20, 2017

Member

Ok. I won't block on that. I much prefer the APIs to be stricter here and not gate based on what we do in http1 but I can live with this.

@jasnell jasnell requested a review from mcollina Oct 17, 2017

@@ -724,7 +729,8 @@ class Http2Session extends EventEmitter {
this[kSocket] = socket;
// Do not use nagle's algorithm
socket.setNoDelay();
if (typeof socket.setNoDelay === 'function')
socket.setNoDelay();
// Disable TLS renegotiation on the socket

This comment has been minimized.

@jasnell

jasnell Oct 17, 2017

Member

A bit further down in this code there is a check for socket.connecting that explicitly defers actions until the socket is connected. With this change, the assumption would be that the non-socket Stream passed in is immediately available for use, which is a perfectly fine assumption to make, IMHO, but I want to make sure that is actually a safe assumption here.

@jasnell

jasnell Oct 17, 2017

Member

A bit further down in this code there is a check for socket.connecting that explicitly defers actions until the socket is connected. With this change, the assumption would be that the non-socket Stream passed in is immediately available for use, which is a perfectly fine assumption to make, IMHO, but I want to make sure that is actually a safe assumption here.

This comment has been minimized.

@addaleax

addaleax Oct 18, 2017

Member

I’m not sure what the alternative would be. We could document socket.connecting/socket.on('connect') as part of the implicit API here?

@addaleax

addaleax Oct 18, 2017

Member

I’m not sure what the alternative would be. We could document socket.connecting/socket.on('connect') as part of the implicit API here?

This comment has been minimized.

@jasnell

jasnell Oct 20, 2017

Member

That would certainly be an option, but given that we're wrapping the custom socket, the likelihood of it even being an issue is pretty low. Let's go with this for now :-)

@jasnell

jasnell Oct 20, 2017

Member

That would certainly be an option, but given that we're wrapping the custom socket, the likelihood of it even being an issue is pretty low. Let's go with this for now :-)

clientSide.end();
}));
req.end();
}

This comment has been minimized.

@jasnell

jasnell Oct 17, 2017

Member

It would be good to include a limited selection of additional variations of other http2 tests, especially those that deal with multiplexing and flow-control just to make sure there are no hidden gotchas. It should be fine, but over-abundance of caution and all that.

@jasnell

jasnell Oct 17, 2017

Member

It would be good to include a limited selection of additional variations of other http2 tests, especially those that deal with multiplexing and flow-control just to make sure there are no hidden gotchas. It should be fine, but over-abundance of caution and all that.

This comment has been minimized.

@addaleax

addaleax Oct 18, 2017

Member

I don’t have that much of an overview over the HTTP/2 tests, it would be good if you could give pointers as to which test files I should be looking at.

(But yes, this should be fine anyway – this doesn’t really deal with anything below the

@addaleax

addaleax Oct 18, 2017

Member

I don’t have that much of an overview over the HTTP/2 tests, it would be good if you could give pointers as to which test files I should be looking at.

(But yes, this should be fine anyway – this doesn’t really deal with anything below the

This comment has been minimized.

@jasnell

jasnell Oct 20, 2017

Member

We can do this separately, actually. Don't worry about it in this PR

@jasnell

jasnell Oct 20, 2017

Member

We can do this separately, actually. Don't worry about it in this PR

@mcollina

Good work. Does this affects benchmarks anyhow?
Can you add a unit test for sendFile as well?

@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax Oct 18, 2017

Member

Does this affects benchmarks anyhow?

I will run them but I’d go with “no” – there really shouldn’t be any measurable perf impact if you don’t use this feature (and even if you do, it’s only during session construction).

Can you add a unit test for sendFile as well?

That sounds reasonable, yes. Done!

Member

addaleax commented Oct 18, 2017

Does this affects benchmarks anyhow?

I will run them but I’d go with “no” – there really shouldn’t be any measurable perf impact if you don’t use this feature (and even if you do, it’s only during session construction).

Can you add a unit test for sendFile as well?

That sounds reasonable, yes. Done!

@apapirovski

LGTM 👍 Just very minor nits.

constructor(type, options, socket) {
super();
if (!socket._handle || !socket._handle._externalStream) {

This comment has been minimized.

@apapirovski

apapirovski Oct 20, 2017

Member

I know this is super nit picky but could we compare to undefined? Anytime we're dealing with an object, because of the existence of document.all (at least as far as V8 is concerned), these truthy/falsey checks are unusually expensive.

@apapirovski

apapirovski Oct 20, 2017

Member

I know this is super nit picky but could we compare to undefined? Anytime we're dealing with an object, because of the existence of document.all (at least as far as V8 is concerned), these truthy/falsey checks are unusually expensive.

This comment has been minimized.

@addaleax

addaleax Oct 20, 2017

Member

Some things in Node’s source explicitly set ._handle on sockets to null (e.g. after disconnecting)… so I’d like to be consistent with TLS here, just to be on the safe side.

these truthy/falsey checks are unusually expensive.

I doubt this makes a noticeable difference compared to the overall cost of setting up the HTTP2 session objects anyway, V8 seems to optimize a function containing only this line reasonable well to me.

@addaleax

addaleax Oct 20, 2017

Member

Some things in Node’s source explicitly set ._handle on sockets to null (e.g. after disconnecting)… so I’d like to be consistent with TLS here, just to be on the safe side.

these truthy/falsey checks are unusually expensive.

I doubt this makes a noticeable difference compared to the overall cost of setting up the HTTP2 session objects anyway, V8 seems to optimize a function containing only this line reasonable well to me.

This comment has been minimized.

@apapirovski

apapirovski Oct 20, 2017

Member

For some reason I thought we were unsetting _handle but if we do null it then this is fine.

@apapirovski

apapirovski Oct 20, 2017

Member

For some reason I thought we were unsetting _handle but if we do null it then this is fine.

Show outdated Hide outdated test/parallel/test-http2-generic-streams-sendfile.js
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => {

This comment has been minimized.

@apapirovski

apapirovski Oct 20, 2017

Member

Nit: ideally a mustCall?

@apapirovski

apapirovski Oct 20, 2017

Member

Nit: ideally a mustCall?

This comment has been minimized.

@addaleax

addaleax Oct 20, 2017

Member

This is just accumulating the data, and that’s checked in an assert (inside a mustCall) anyway

@addaleax

addaleax Oct 20, 2017

Member

This is just accumulating the data, and that’s checked in an assert (inside a mustCall) anyway

This comment has been minimized.

@jasnell

jasnell Oct 20, 2017

Member

mustCall's on data events can be problematic. If anything, a mustCallAtLeast would be ok.

@jasnell

jasnell Oct 20, 2017

Member

mustCall's on data events can be problematic. If anything, a mustCallAtLeast would be ok.

This comment has been minimized.

@apapirovski

apapirovski Oct 20, 2017

Member

Sorry, this was strictly about the consistency of these calls. In other tests with this PR, data events have mustCall. It sets a good example for newer contributors when there's consistency to where we mustCall and where we don't. Or we could leave a comment explaining why not.

When I started writing tests and contributing to node I had a bit of confusion around this because it wasn't 100% consistent across tests.

But as I mentioned, this is just a very minor nit. :)

@apapirovski

apapirovski Oct 20, 2017

Member

Sorry, this was strictly about the consistency of these calls. In other tests with this PR, data events have mustCall. It sets a good example for newer contributors when there's consistency to where we mustCall and where we don't. Or we could leave a comment explaining why not.

When I started writing tests and contributing to node I had a bit of confusion around this because it wasn't 100% consistent across tests.

But as I mentioned, this is just a very minor nit. :)

This comment has been minimized.

@addaleax

addaleax Oct 20, 2017

Member

Fwiw, the other call is somewhat intentionally checking that the data is sent through in a single chunk :) I’ve added 2a666de as a comment for that

@addaleax

addaleax Oct 20, 2017

Member

Fwiw, the other call is somewhat intentionally checking that the data is sent through in a single chunk :) I’ve added 2a666de as a comment for that

Show outdated Hide outdated test/common/README.md
@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax
Member

addaleax commented Oct 22, 2017

Fresh CI: https://ci.nodejs.org/job/node-test-commit/13370/

This should be ready.

addaleax added some commits Oct 17, 2017

src: allow top-level calls into JSStream
Allow `JSStream` instances to be used more flexibly by explicitly
enabling calls that have no JS stack below them.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
src: turn JS stream into a full duplex
Remove unused methods for reading data from `JSStream` and add
those required for emitting data or an EOF event to the JS side,
in essentially the same way that `LibuvStreamWrap` does it.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
http2: support generic `Duplex` streams
Support generic `Duplex` streams through using `StreamWrap`
on the server and client sides, and adding a `createConnection`
method option similar to what the HTTP/1 API provides.

Since HTTP2 is, as a protocol, independent of its underlying transport
layer, Node.js should not enforce any restrictions on what streams
its internals may use.

Ref: #16256
PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to addaleax/node that referenced this pull request Oct 22, 2017

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: nodejs#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax
Member

addaleax commented Oct 23, 2017

Landed in ba4a0a6...ab16eec

@addaleax addaleax closed this Oct 23, 2017

@addaleax addaleax deleted the addaleax:http2-generic-streams branch Oct 23, 2017

addaleax added a commit that referenced this pull request Oct 23, 2017

src: allow top-level calls into JSStream
Allow `JSStream` instances to be used more flexibly by explicitly
enabling calls that have no JS stack below them.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit that referenced this pull request Oct 23, 2017

src: turn JS stream into a full duplex
Remove unused methods for reading data from `JSStream` and add
those required for emitting data or an EOF event to the JS side,
in essentially the same way that `LibuvStreamWrap` does it.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit that referenced this pull request Oct 23, 2017

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit that referenced this pull request Oct 23, 2017

http2: support generic `Duplex` streams
Support generic `Duplex` streams through using `StreamWrap`
on the server and client sides, and adding a `createConnection`
method option similar to what the HTTP/1 API provides.

Since HTTP2 is, as a protocol, independent of its underlying transport
layer, Node.js should not enforce any restrictions on what streams
its internals may use.

Ref: #16256
PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Oct 23, 2017

src: allow top-level calls into JSStream
Allow `JSStream` instances to be used more flexibly by explicitly
enabling calls that have no JS stack below them.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Oct 23, 2017

src: turn JS stream into a full duplex
Remove unused methods for reading data from `JSStream` and add
those required for emitting data or an EOF event to the JS side,
in essentially the same way that `LibuvStreamWrap` does it.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Oct 23, 2017

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Oct 23, 2017

http2: support generic `Duplex` streams
Support generic `Duplex` streams through using `StreamWrap`
on the server and client sides, and adding a `createConnection`
method option similar to what the HTTP/1 API provides.

Since HTTP2 is, as a protocol, independent of its underlying transport
layer, Node.js should not enforce any restrictions on what streams
its internals may use.

Ref: #16256
PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Oct 24, 2017

2017-10-24, Node.js Version 8.8.0 (Current)
Notable Changes:

* crypto:
  - expose ECDH class
    #8188
* http2:
  - http2 is now exposed by defualt without the need for a flag
    #15685
  - a new environment varible NODE\_NO\_HTTP2 has been added to allow
    userland http2 to be required
    #15685
  - support has been added for generic `Duplex` streams
    #16269
* module:
  - resolve and instantiate loader pipeline hooks have been added to
    the ESM lifecycle
    #15445
* zlib:
  - CVE-2017-14919 - In zlib v1.2.9, a change was made that causes an
    error to be raised when a raw deflate stream is initialized with
    windowBits set to 8. On some versions this crashes Node and you
    cannot recover from it, while on some versions it throws an
    exception. Node.js will now gracefully set windowBits to 9
    replicating the legacy behavior to avoid a DOS vector.
    nodejs-private/node-private#95

PR-URL: nodejs-private/node-private#98

addaleax added a commit to ayojs/ayo that referenced this pull request Oct 26, 2017

src: allow top-level calls into JSStream
Allow `JSStream` instances to be used more flexibly by explicitly
enabling calls that have no JS stack below them.

PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Oct 26, 2017

src: turn JS stream into a full duplex
Remove unused methods for reading data from `JSStream` and add
those required for emitting data or an EOF event to the JS side,
in essentially the same way that `LibuvStreamWrap` does it.

PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Oct 26, 2017

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Oct 26, 2017

http2: support generic `Duplex` streams
Support generic `Duplex` streams through using `StreamWrap`
on the server and client sides, and adding a `createConnection`
method option similar to what the HTTP/1 API provides.

Since HTTP2 is, as a protocol, independent of its underlying transport
layer, Node.js should not enforce any restrictions on what streams
its internals may use.

Ref: nodejs/node#16256
PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Oct 26, 2017

2017-10-24, Node.js Version 8.8.0 (Current)
Notable Changes:

* crypto:
  - expose ECDH class
    nodejs/node#8188
* http2:
  - http2 is now exposed by defualt without the need for a flag
    nodejs/node#15685
  - a new environment varible NODE\_NO\_HTTP2 has been added to allow
    userland http2 to be required
    nodejs/node#15685
  - support has been added for generic `Duplex` streams
    nodejs/node#16269
* module:
  - resolve and instantiate loader pipeline hooks have been added to
    the ESM lifecycle
    nodejs/node#15445
* zlib:
  - CVE-2017-14919 - In zlib v1.2.9, a change was made that causes an
    error to be raised when a raw deflate stream is initialized with
    windowBits set to 8. On some versions this crashes Node and you
    cannot recover from it, while on some versions it throws an
    exception. Node.js will now gracefully set windowBits to 9
    replicating the legacy behavior to avoid a DOS vector.
    nodejs-private/node-private#95

PR-URL: nodejs-private/node-private#98

addaleax added a commit to ayojs/ayo that referenced this pull request Dec 7, 2017

src: allow top-level calls into JSStream
Allow `JSStream` instances to be used more flexibly by explicitly
enabling calls that have no JS stack below them.

PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Dec 7, 2017

src: turn JS stream into a full duplex
Remove unused methods for reading data from `JSStream` and add
those required for emitting data or an EOF event to the JS side,
in essentially the same way that `LibuvStreamWrap` does it.

PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Dec 7, 2017

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Dec 7, 2017

http2: support generic `Duplex` streams
Support generic `Duplex` streams through using `StreamWrap`
on the server and client sides, and adding a `createConnection`
method option similar to what the HTTP/1 API provides.

Since HTTP2 is, as a protocol, independent of its underlying transport
layer, Node.js should not enforce any restrictions on what streams
its internals may use.

Ref: nodejs/node#16256
PR-URL: nodejs/node#16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to ayojs/ayo that referenced this pull request Dec 7, 2017

2017-10-24, Node.js Version 8.8.0 (Current)
Notable Changes:

* crypto:
  - expose ECDH class
    nodejs/node#8188
* http2:
  - http2 is now exposed by defualt without the need for a flag
    nodejs/node#15685
  - a new environment varible NODE\_NO\_HTTP2 has been added to allow
    userland http2 to be required
    nodejs/node#15685
  - support has been added for generic `Duplex` streams
    nodejs/node#16269
* module:
  - resolve and instantiate loader pipeline hooks have been added to
    the ESM lifecycle
    nodejs/node#15445
* zlib:
  - CVE-2017-14919 - In zlib v1.2.9, a change was made that causes an
    error to be raised when a raw deflate stream is initialized with
    windowBits set to 8. On some versions this crashes Node and you
    cannot recover from it, while on some versions it throws an
    exception. Node.js will now gracefully set windowBits to 9
    replicating the legacy behavior to avoid a DOS vector.
    nodejs-private/node-private#95

PR-URL: nodejs-private/node-private#98

MylesBorins added a commit that referenced this pull request Jan 22, 2018

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

@MylesBorins MylesBorins referenced this pull request Jan 24, 2018

Merged

v6.13.0 proposal #18342

MylesBorins added a commit that referenced this pull request Feb 11, 2018

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Feb 12, 2018

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Feb 12, 2018

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Feb 13, 2018

test: add `makeDuplexPair()` helper
Add a utility for adding simple, streams-API based duplex pairs.

PR-URL: #16269
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment