Skip to content

http2: refactor read mechanism - #18030

Closed
addaleax wants to merge 2 commits into
nodejs:masterfrom
addaleax:http2-inbound-nocopy
Closed

http2: refactor read mechanism#18030
addaleax wants to merge 2 commits into
nodejs:masterfrom
addaleax:http2-inbound-nocopy

Conversation

@addaleax

@addaleaxaddaleax commented Jan 8, 2018

Copy link
Copy Markdown
Member

The first commit is from #18020 to avoid merge conflicts.

  • src: introduce internal buffer slice constructor

    Add a C++ variant of Buffer.from(arrayBuffer, offset, length).

  • http2: refactor read mechanism

    Refactor the read mechanism to completely avoid copying.

    Instead of copying individual DATA frame contents into buffers,
    create ArrayBuffer instances for all socket reads and emit
    slices of those ArrayBuffers to JS.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included (note that the added test passes independently of this change)
  • commit message follows commit guidelines
Affected core subsystem(s)

/cc @nodejs/http2

@addaleaxaddaleax added blocked PRs that are blocked by other issues or PRs. http2 Issues or PRs related to the http2 subsystem. labels Jan 8, 2018
@nodejs-github-botnodejs-github-bot added the lib / src Issues and PRs related to general changes in the lib or src directory. label Jan 8, 2018
Comment threadsrc/node_internals.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to explicitly note that a HandleScope must have been opened before calling this function?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimothyGu I think that’s kind of explicit in the fact that this returns a MaybeLocal; that’s never valid without a HandleScope, right?

(Or, the other way around: The same is true of the other buffer constructors, but we don’t mention it there.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's certainly true. But the other Buffer constructors open a HandleScope themselves so I was wondering.

@addaleaxaddaleaxJan 8, 2018

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimothyGu I removed it in this case because, as far as I can tell, all the temporary handles created here refer to objects that are kept alive be the returned Buffer instance anyway.

If my understanding is correct, I think they could be removed in the other cases as well, but I am not 100 % sure and since some of them are public API I left them the way they were.

Comment threadtest/common/index.js Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the returned function return a promise as well, so that one could chain the functions returned by mustCallAsync?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimothyGu yup, done!

Comment threadlib/perf_hooks.js Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer we didn't define these here, but rather in the HTTP2 part. I think these are also defined for every single instance, which will increase overhead.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcollina Can you comment that on @jasnell’s #18020? :)

@jasnelljasnell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Did you benchmark this at all? It should yield a nice modest boost.

@addaleax

Copy link
Copy Markdown
MemberAuthor

@jasnell I got about + 3 % in the simple benchmark but I’ll kick off a benchmark CI after #18020 has been merged :)

Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
Refactor the read mechanism to completely avoid copying.
Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
@addaleaxaddaleax removed the blocked PRs that are blocked by other issues or PRs. label Jan 13, 2018
@addaleax
addaleaxforce-pushed the http2-inbound-nocopy branch from a2c195f to d6fcbedCompareJanuary 13, 2018 14:38
@addaleax

Copy link
Copy Markdown
MemberAuthor

@addaleax

Copy link
Copy Markdown
MemberAuthor

@nodejs/benchmarking https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/93/console says

Error: Requested benchmarker 'h2load' is not installed

Is there anything we can do about that?

@jasnell

Copy link
Copy Markdown
Member

Ping @nodejs/build

@addaleaxaddaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Jan 18, 2018
@addaleax

Copy link
Copy Markdown
MemberAuthor

Landed in da30788, 0625627

@addaleax
addaleax deleted the http2-inbound-nocopy branch January 18, 2018 21:50
addaleax added a commit that referenced this pull request Jan 18, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
addaleax added a commit that referenced this pull request Jan 18, 2018
Refactor the read mechanism to completely avoid copying.
Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Refactor the read mechanism to completely avoid copying.
Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
@evanlucasevanlucas mentioned this pull request Jan 30, 2018
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Refactor the read mechanism to completely avoid copying.
Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
@MylesBorins

Copy link
Copy Markdown
Contributor

Should this be backported to v8.x-staging? If yes please follow the guide and raise a backport PR, if not let me know or add the dont-land-on label.

@addaleaxaddaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 1, 2018
kjin pushed a commit to kjin/node that referenced this pull request May 1, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
kjin pushed a commit to kjin/node that referenced this pull request May 1, 2018
Refactor the read mechanism to completely avoid copying.
Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 2, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
Backport-PR-URL: #20456
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 2, 2018
Refactor the read mechanism to completely avoid copying.
Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
Backport-PR-URL: #20456
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
@MylesBorinsMylesBorins mentioned this pull request May 2, 2018
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Refactor the read mechanism to completely avoid copying.
Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

http2Issues or PRs related to the http2 subsystem.lib / srcIssues and PRs related to general changes in the lib or src directory.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@addaleax@jasnell@MylesBorins@mcollina@TimothyGu@nodejs-github-bot