Skip to content
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

src: refactor HasWriteQueue() away #18019

Closed
wants to merge 3 commits into from

Conversation

addaleax
Copy link
Member

@addaleax addaleax commented Jan 6, 2018

  • process: use more direct sync I/O for stdio

    This avoids routing writes through the full LibuvStreamWrap
    write machinery. In particular, it enables the next commit,
    because otherwise the callback passed to _write()
    would not be called synchronously for pipes on Windows
    (because the latter does not support uv_try_write(),
    even for blocking I/O).

  • src: remove HasWriteQueue()

    Tests are passing without it now, and this otherwise makes the
    code harder to reason about because the async flag on the
    write request object would not be set even though the callback
    would still be pending.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines
Affected core subsystem(s)

src/stream_base

/cc @apapirovski

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Jan 6, 2018
@addaleax
Copy link
Member Author

addaleax commented Jan 6, 2018

Copy link
Member

@apapirovski apapirovski left a comment

Choose a reason for hiding this comment

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

SGTM if the CI is green. When I worked on this last, there were some cross-system issues around having net writes be async with no actual write queue (which is why we used to have the check for writeQueueSize right in _writeGeneric).

@addaleax
Copy link
Member Author

addaleax commented Jan 6, 2018

@apapirovski I’m not sure if that’s what you’re talking about, but the first commit here works around the fact that, while pipes on Windows can be set to blocking, they always need DoWrite() rather than DoTryWrite(); and the second thing was our main REPL test, where some over-specific reliance on chunk boundaries was refactored away in #17926

@apapirovski
Copy link
Member

@addaleax It's been too long to remember. The bit re: Windows pipes makes sense and the code looks good to me. I feel like there might've been a different issue on linux, although it might've just been the repl test, as you mentioned. Either way, the code looks good to me. 👍

(this._handle instanceof Pipe) &&
process.platform === 'win32') {
// Make stdout and stderr blocking on Windows
var err = this._handle.setBlocking(true);
if (err)
throw errnoException(err, 'setBlocking');

this._writev = null;
this._write = makeSyncWrite(fd);
Copy link
Member

Choose a reason for hiding this comment

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

Can we assign fd to a symbol property here and do the if logic in Socket.prototype._write to avoid the additional closure?

Copy link
Member Author

Choose a reason for hiding this comment

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

@joyeecheung I have thought about making fd a property for all net.Sockets, but I’m not sure whether that’s a good idea or not.

We could add a symbol, but for now I’d probably leave the code as it is, especially given that the worst case is that this might create 2 closures for the entire process…

@addaleax addaleax added the wip Issues and PRs that are still a work in progress. label Jan 9, 2018
This avoids routing writes through the full LibuvStreamWrap
write machinery. In particular, it enables the next commit,
because otherwise the callback passed to `_write()`
would not be called synchronously for pipes on Windows
(because the latter does not support `uv_try_write()`,
even for blocking I/O).
Tests are passing without it, and this otherwise makes the
code harder to reason about because the `async` flag on the
write request object would not be set even though the callback
would still be pending.
@addaleax addaleax removed the wip Issues and PRs that are still a work in progress. label Jan 10, 2018
@addaleax
Copy link
Member Author

addaleax commented Jan 10, 2018

Did some experimenting to keep the benchmarks happy. I ran these on a largely unused machine, since the benchmark CI is currently blocked, for the combination of parameters that seemed most problematic, with 90 runs to be on the safe side:

$ ./node benchmark/compare.js --runs 90 --new ./node --old ./node-master --set type=utf --set len=10240 --filter net-pipe net | Rscript benchmark/compare.R
[00:15:40|% 100| 1/1 files | 180/180 runs | 1/1 configs]: Done
                                             improvement confidence   p.value
 net/net-pipe.js dur=5 type="utf" len=10240      0.07 %            0.8542763

I’m good with landing this in this state, there does not seem to be any performance difference anymore. (This would fit the symptoms – HasWriteQueue() being false after we did try DoTryWrite() seems like a condition that should be very unlikely. That only happened for not-all-buffers calls to writev(), which would be a kind of thing that should happen frequently in that benchmark, and it’s probably a good idea for performance to make these DoTryWrite() calls anyway.)

New CI: https://ci.nodejs.org/job/node-test-pull-request/12493/

Could somebody review the last commit here?

Edit: Scheduled benchmark CI @ https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/94/

@jasnell
Copy link
Member

jasnell commented Jan 10, 2018

last commit lgtm

@addaleax addaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Jan 10, 2018
@addaleax
Copy link
Member Author

Landed in c84582c...02fef8a

@addaleax addaleax closed this Jan 14, 2018
@addaleax addaleax deleted the no-has-write-queue branch January 14, 2018 13:47
@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Jan 14, 2018
addaleax added a commit that referenced this pull request Jan 14, 2018
This avoids routing writes through the full LibuvStreamWrap
write machinery. In particular, it enables the next commit,
because otherwise the callback passed to `_write()`
would not be called synchronously for pipes on Windows
(because the latter does not support `uv_try_write()`,
even for blocking I/O).

PR-URL: #18019
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
addaleax added a commit that referenced this pull request Jan 14, 2018
Tests are passing without it, and this otherwise makes the
code harder to reason about because the `async` flag on the
write request object would not be set even though the callback
would still be pending.

PR-URL: #18019
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
addaleax added a commit that referenced this pull request Feb 26, 2018
Tests are passing without it, and this otherwise makes the
code harder to reason about because the `async` flag on the
write request object would not be set even though the callback
would still be pending.

PR-URL: #18019
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
addaleax added a commit that referenced this pull request Feb 26, 2018
addaleax added a commit that referenced this pull request Feb 26, 2018
This broke writing non-ASCII data to the console on Windows because
the result would be codepage-dependent.

This partially reverts 8b751f7.

Fixes: #18189
Refs: #18019

PR-URL: #18214
Fixes: #18189
Refs: #18019
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
addaleax pushed a commit that referenced this pull request Feb 26, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
#17493. It was fixed in
#18019.

PR-URL: #18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
addaleax added a commit that referenced this pull request Feb 26, 2018
This avoids routing writes through the full LibuvStreamWrap
write machinery. In particular, it enables the next commit,
because otherwise the callback passed to `_write()`
would not be called synchronously for pipes on Windows
(because the latter does not support `uv_try_write()`,
even for blocking I/O).

PR-URL: #18019
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
addaleax added a commit that referenced this pull request Feb 26, 2018
Tests are passing without it, and this otherwise makes the
code harder to reason about because the `async` flag on the
write request object would not be set even though the callback
would still be pending.

PR-URL: #18019
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
addaleax added a commit that referenced this pull request Feb 26, 2018
addaleax added a commit that referenced this pull request Feb 26, 2018
This broke writing non-ASCII data to the console on Windows because
the result would be codepage-dependent.

This partially reverts 8b751f7.

Fixes: #18189
Refs: #18019

PR-URL: #18214
Fixes: #18189
Refs: #18019
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
addaleax pushed a commit that referenced this pull request Feb 26, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
#17493. It was fixed in
#18019.

PR-URL: #18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
MylesBorins pushed a commit that referenced this pull request Feb 26, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
#17493. It was fixed in
#18019.

PR-URL: #18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
@addaleax addaleax mentioned this pull request Feb 27, 2018
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
This broke writing non-ASCII data to the console on Windows because
the result would be codepage-dependent.

This partially reverts 8b751f7.

Fixes: nodejs#18189
Refs: nodejs#18019

PR-URL: nodejs#18214
Fixes: nodejs#18189
Refs: nodejs#18019
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
nodejs#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
nodejs#17493. It was fixed in
nodejs#18019.

PR-URL: nodejs#18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
@codebytere
Copy link
Member

codebytere commented Aug 2, 2018

@addaleax should this be backported to v8.x or has it not yet baked sufficiently?

MylesBorins pushed a commit that referenced this pull request Aug 7, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
#17493. It was fixed in
#18019.

PR-URL: #18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
MylesBorins pushed a commit that referenced this pull request Aug 7, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
#17493. It was fixed in
#18019.

PR-URL: #18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
MylesBorins pushed a commit that referenced this pull request Aug 9, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
#17493. It was fixed in
#18019.

PR-URL: #18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
MylesBorins pushed a commit that referenced this pull request Aug 16, 2018
Add two regression tests for stdio over pipes.

test-stdio-pipe-access tests if accessing stdio pipe that is being read
by another process does not deadlocks Node.js. This was reported in
#10836 and was fixed in v8.3.0.
The deadlock would happen intermittently, so we run the test 5 times.

test-stdio-pipe-redirect tests if redirecting one child process stdin to
another process stdout does not crash Node as reported in
#17493. It was fixed in
#18019.

PR-URL: #18614
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
@MylesBorins MylesBorins added backported-to-v8.x and removed baking-for-lts PRs that need to wait before landing in a LTS release. labels Aug 17, 2018
@MylesBorins
Copy link
Contributor

I've gone ahead and landed this on v8.x as it fixes a broken test that was already landed

20f6aae was not included as hasWriteQueue did not exist on 8.x

MylesBorins pushed a commit that referenced this pull request Aug 17, 2018
This avoids routing writes through the full LibuvStreamWrap
write machinery. In particular, it enables the next commit,
because otherwise the callback passed to `_write()`
would not be called synchronously for pipes on Windows
(because the latter does not support `uv_try_write()`,
even for blocking I/O).

PR-URL: #18019
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
MylesBorins pushed a commit that referenced this pull request Aug 17, 2018
MylesBorins pushed a commit that referenced this pull request Aug 17, 2018
This broke writing non-ASCII data to the console on Windows because
the result would be codepage-dependent.

This partially reverts 8b751f7.

Fixes: #18189
Refs: #18019

PR-URL: #18214
Fixes: #18189
Refs: #18019
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
@MylesBorins MylesBorins mentioned this pull request Aug 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues 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.

9 participants