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 stream callbacks and ownership #18334

Closed
wants to merge 2 commits into from

Conversation

addaleax
Copy link
Member

Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean consume_ flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

Benchmark results show no significant changes:
$ ./node benchmark/compare.js --runs 5 --new ./node --old ./node-master net | Rscript benchmark/compare.R
[00:43:05|% 100| 8/8 files | 10/10 runs | 6/6 configs]: Done
                                                                      improvement confidence     p.value
 net/net-c2s-cork.js dur=5 type="buf" len=1024                           -0.80 %            0.720985414
 net/net-c2s-cork.js dur=5 type="buf" len=128                            -3.50 %            0.278786279
 net/net-c2s-cork.js dur=5 type="buf" len=16                             -4.44 %          * 0.010458284
 net/net-c2s-cork.js dur=5 type="buf" len=32                             -0.51 %            0.445313528
 net/net-c2s-cork.js dur=5 type="buf" len=4                              -1.57 %            0.074816557
 net/net-c2s-cork.js dur=5 type="buf" len=512                            -0.25 %            0.926451422
 net/net-c2s-cork.js dur=5 type="buf" len=64                              1.66 %          * 0.020469582
 net/net-c2s-cork.js dur=5 type="buf" len=8                              -0.18 %            0.739524856
 net/net-c2s.js dur=5 type="asc" len=102400                              -0.22 %            0.904819514
 net/net-c2s.js dur=5 type="asc" len=16777216                             0.34 %            0.862222556
 net/net-c2s.js dur=5 type="buf" len=102400                              -0.45 %            0.755593966
 net/net-c2s.js dur=5 type="buf" len=16777216                             1.87 %            0.477896886
 net/net-c2s.js dur=5 type="utf" len=102400                              -0.30 %            0.572739665
 net/net-c2s.js dur=5 type="utf" len=16777216                             1.18 %            0.369268245
 net/net-pipe.js dur=5 type="asc" len=102400                              1.18 %            0.368102481
 net/net-pipe.js dur=5 type="asc" len=16777216                            0.41 %            0.659646192
 net/net-pipe.js dur=5 type="buf" len=102400                              1.65 %            0.148484290
 net/net-pipe.js dur=5 type="buf" len=16777216                            0.05 %            0.949649889
 net/net-pipe.js dur=5 type="utf" len=102400                              0.65 %            0.463140117
 net/net-pipe.js dur=5 type="utf" len=16777216                            0.57 %            0.531757174
 net/net-s2c.js dur=5 type="asc" len=102400                               0.01 %            0.994663657
 net/net-s2c.js dur=5 type="asc" len=16777216                             0.55 %            0.690648594
 net/net-s2c.js dur=5 type="buf" len=102400                               1.06 %            0.162661878
 net/net-s2c.js dur=5 type="buf" len=16777216                             2.21 %            0.458328732
 net/net-s2c.js dur=5 type="utf" len=102400                               0.47 %            0.346382821
 net/net-s2c.js dur=5 type="utf" len=16777216                            -1.19 %            0.075676276
 net/net-wrap-js-stream-passthrough.js dur=5 type="asc" len=102400       -5.01 %            0.566507367
 net/net-wrap-js-stream-passthrough.js dur=5 type="asc" len=16777216      1.81 %            0.382296906
 net/net-wrap-js-stream-passthrough.js dur=5 type="buf" len=102400       -4.32 %            0.543143575
 net/net-wrap-js-stream-passthrough.js dur=5 type="buf" len=16777216      0.12 %            0.774690856
 net/net-wrap-js-stream-passthrough.js dur=5 type="utf" len=102400        2.33 %            0.152586683
 net/net-wrap-js-stream-passthrough.js dur=5 type="utf" len=16777216      0.50 %            0.687525683
 net/tcp-raw-c2s.js dur=5 type="asc" len=102400                           0.05 %            0.917082371
 net/tcp-raw-c2s.js dur=5 type="asc" len=16777216                         4.17 %         ** 0.005564067
 net/tcp-raw-c2s.js dur=5 type="buf" len=102400                           0.56 %          * 0.037673166
 net/tcp-raw-c2s.js dur=5 type="buf" len=16777216                         0.77 %         ** 0.006890503
 net/tcp-raw-c2s.js dur=5 type="utf" len=102400                          -0.50 %            0.397862701
 net/tcp-raw-c2s.js dur=5 type="utf" len=16777216                         1.00 %            0.300638263
 net/tcp-raw-pipe.js dur=5 type="asc" len=102400                          0.82 %            0.722353484
 net/tcp-raw-pipe.js dur=5 type="asc" len=16777216                       15.00 %            0.070918075
 net/tcp-raw-pipe.js dur=5 type="buf" len=102400                         -1.03 %            0.819639125
 net/tcp-raw-pipe.js dur=5 type="buf" len=16777216                       18.35 %            0.329069149
 net/tcp-raw-pipe.js dur=5 type="utf" len=102400                         -0.27 %            0.984576346
 net/tcp-raw-pipe.js dur=5 type="utf" len=16777216                        2.78 %            0.362840470
 net/tcp-raw-s2c.js dur=5 type="asc" len=102400                          -0.15 %            0.820491736
 net/tcp-raw-s2c.js dur=5 type="asc" len=16777216                        -0.42 %            0.813160796
 net/tcp-raw-s2c.js dur=5 type="buf" len=102400                           0.26 %            0.615102013
 net/tcp-raw-s2c.js dur=5 type="buf" len=16777216                        -2.16 %            0.464289164
 net/tcp-raw-s2c.js dur=5 type="utf" len=102400                          -0.33 %            0.383964275
 net/tcp-raw-s2c.js dur=5 type="utf" len=16777216                         1.08 %            0.224603980

As a heads up, after this I’d like to also refactor the writable side a bit more by removing WriteWrap and ShutdownWrap as explicit classes; I have some WIP work but haven’t gotten that to pass all TLS tests yet…

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

src

@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 24, 2018
@addaleax
Copy link
Member Author

@jasnell
Copy link
Member

jasnell commented Jan 24, 2018

Generally +1 on this but it's going to take a bit to review.

ping @mcollina

@addaleax
Copy link
Member Author

CITGM blew up with ENOSPC on AIX but other than that I think we’re good. (Will run CITGM again at a later point to make sure).

@addaleax
Copy link
Member Author

Pushed another commit that simplifies the passing of handles to/from child processes quite a bit.

I realize that this PR might take a while to review, but I’d like to invite any @nodejs/collaborators who want to to do that and watch out for bits that aren’t immediately clear here, because a main goal of this PR is increasing readability & adding documentation to the C++ code parts.

@@ -123,89 +124,113 @@ class WriteWrap : public ReqWrap<uv_write_t>,
const size_t storage_size_;
};

class StreamResource {

// This is the generic interface for objects that control Node's C++ streams.
Copy link
Member

Choose a reason for hiding this comment

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

extreme nit: s/Node's/Node.js'

@apapirovski
Copy link
Member

I've started reviewing and very much +1 on this change but won't get a chance to finish until later today or tomorrow morning.

@addaleax
Copy link
Member Author

@apapirovski I definitely won’t land this before next week, there’s no rush. :)

@jasnell
Copy link
Member

jasnell commented Jan 25, 2018

The changes look very good overall (thus the sign off). I would like to see some benchmark runs. I don't anticipate much impact, but given how much code this touches, it would be worthwhile.

@jasnell
Copy link
Member

jasnell commented Jan 25, 2018

ha! nevermind! I missed the collapsed section in the original post :-)

@gibfahn
Copy link
Member

gibfahn commented Jan 25, 2018

@addaleax CitGM should be better now.

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.

LGTM 👍

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM, this is very solid work.

Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean `consume_` flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

Benchmark results show no significant changes:

    $ ./node benchmark/compare.js --runs 5 --new ./node --old ./node-master net | Rscript benchmark/compare.R
    [00:43:05|% 100| 8/8 files | 10/10 runs | 6/6 configs]: Done
                                                                          improvement confidence     p.value
     net/net-c2s-cork.js dur=5 type="buf" len=1024                           -0.80 %            0.720985414
     net/net-c2s-cork.js dur=5 type="buf" len=128                            -3.50 %            0.278786279
     net/net-c2s-cork.js dur=5 type="buf" len=16                             -4.44 %          * 0.010458284
     net/net-c2s-cork.js dur=5 type="buf" len=32                             -0.51 %            0.445313528
     net/net-c2s-cork.js dur=5 type="buf" len=4                              -1.57 %            0.074816557
     net/net-c2s-cork.js dur=5 type="buf" len=512                            -0.25 %            0.926451422
     net/net-c2s-cork.js dur=5 type="buf" len=64                              1.66 %          * 0.020469582
     net/net-c2s-cork.js dur=5 type="buf" len=8                              -0.18 %            0.739524856
     net/net-c2s.js dur=5 type="asc" len=102400                              -0.22 %            0.904819514
     net/net-c2s.js dur=5 type="asc" len=16777216                             0.34 %            0.862222556
     net/net-c2s.js dur=5 type="buf" len=102400                              -0.45 %            0.755593966
     net/net-c2s.js dur=5 type="buf" len=16777216                             1.87 %            0.477896886
     net/net-c2s.js dur=5 type="utf" len=102400                              -0.30 %            0.572739665
     net/net-c2s.js dur=5 type="utf" len=16777216                             1.18 %            0.369268245
     net/net-pipe.js dur=5 type="asc" len=102400                              1.18 %            0.368102481
     net/net-pipe.js dur=5 type="asc" len=16777216                            0.41 %            0.659646192
     net/net-pipe.js dur=5 type="buf" len=102400                              1.65 %            0.148484290
     net/net-pipe.js dur=5 type="buf" len=16777216                            0.05 %            0.949649889
     net/net-pipe.js dur=5 type="utf" len=102400                              0.65 %            0.463140117
     net/net-pipe.js dur=5 type="utf" len=16777216                            0.57 %            0.531757174
     net/net-s2c.js dur=5 type="asc" len=102400                               0.01 %            0.994663657
     net/net-s2c.js dur=5 type="asc" len=16777216                             0.55 %            0.690648594
     net/net-s2c.js dur=5 type="buf" len=102400                               1.06 %            0.162661878
     net/net-s2c.js dur=5 type="buf" len=16777216                             2.21 %            0.458328732
     net/net-s2c.js dur=5 type="utf" len=102400                               0.47 %            0.346382821
     net/net-s2c.js dur=5 type="utf" len=16777216                            -1.19 %            0.075676276
     net/net-wrap-js-stream-passthrough.js dur=5 type="asc" len=102400       -5.01 %            0.566507367
     net/net-wrap-js-stream-passthrough.js dur=5 type="asc" len=16777216      1.81 %            0.382296906
     net/net-wrap-js-stream-passthrough.js dur=5 type="buf" len=102400       -4.32 %            0.543143575
     net/net-wrap-js-stream-passthrough.js dur=5 type="buf" len=16777216      0.12 %            0.774690856
     net/net-wrap-js-stream-passthrough.js dur=5 type="utf" len=102400        2.33 %            0.152586683
     net/net-wrap-js-stream-passthrough.js dur=5 type="utf" len=16777216      0.50 %            0.687525683
     net/tcp-raw-c2s.js dur=5 type="asc" len=102400                           0.05 %            0.917082371
     net/tcp-raw-c2s.js dur=5 type="asc" len=16777216                         4.17 %         ** 0.005564067
     net/tcp-raw-c2s.js dur=5 type="buf" len=102400                           0.56 %          * 0.037673166
     net/tcp-raw-c2s.js dur=5 type="buf" len=16777216                         0.77 %         ** 0.006890503
     net/tcp-raw-c2s.js dur=5 type="utf" len=102400                          -0.50 %            0.397862701
     net/tcp-raw-c2s.js dur=5 type="utf" len=16777216                         1.00 %            0.300638263
     net/tcp-raw-pipe.js dur=5 type="asc" len=102400                          0.82 %            0.722353484
     net/tcp-raw-pipe.js dur=5 type="asc" len=16777216                       15.00 %            0.070918075
     net/tcp-raw-pipe.js dur=5 type="buf" len=102400                         -1.03 %            0.819639125
     net/tcp-raw-pipe.js dur=5 type="buf" len=16777216                       18.35 %            0.329069149
     net/tcp-raw-pipe.js dur=5 type="utf" len=102400                         -0.27 %            0.984576346
     net/tcp-raw-pipe.js dur=5 type="utf" len=16777216                        2.78 %            0.362840470
     net/tcp-raw-s2c.js dur=5 type="asc" len=102400                          -0.15 %            0.820491736
     net/tcp-raw-s2c.js dur=5 type="asc" len=16777216                        -0.42 %            0.813160796
     net/tcp-raw-s2c.js dur=5 type="buf" len=102400                           0.26 %            0.615102013
     net/tcp-raw-s2c.js dur=5 type="buf" len=16777216                        -2.16 %            0.464289164
     net/tcp-raw-s2c.js dur=5 type="utf" len=102400                          -0.33 %            0.383964275
     net/tcp-raw-s2c.js dur=5 type="utf" len=16777216                         1.08 %            0.224603980

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Instead of passing along the handle object, just set it as a
property on the stream handle object and let the read handler
grab it from there.

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@addaleax addaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Jan 31, 2018
@addaleax
Copy link
Member Author

Fresh CI: https://ci.nodejs.org/job/node-test-commit/15821/
Fresh CITGM: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/1246/

I’d like to land this once these come back good.

@BridgeAR
Copy link
Member

BridgeAR commented Feb 1, 2018

Landed in 7c4b09b, 5898dc3

@BridgeAR BridgeAR closed this Feb 1, 2018
BridgeAR pushed a commit to BridgeAR/node that referenced this pull request Feb 1, 2018
Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean `consume_` flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
BridgeAR pushed a commit to BridgeAR/node that referenced this pull request Feb 1, 2018
Instead of passing along the handle object, just set it as a
property on the stream handle object and let the read handler
grab it from there.

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@addaleax addaleax deleted the stream-listener branch February 1, 2018 17:12
@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Feb 1, 2018
@MylesBorins
Copy link
Contributor

Should this be backported to v9.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.

addaleax added a commit to addaleax/node that referenced this pull request Feb 26, 2018
Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean `consume_` flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
addaleax added a commit to addaleax/node that referenced this pull request Feb 26, 2018
Instead of passing along the handle object, just set it as a
property on the stream handle object and let the read handler
grab it from there.

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
addaleax added a commit that referenced this pull request Feb 26, 2018
Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean `consume_` flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

PR-URL: #18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
addaleax added a commit that referenced this pull request Feb 26, 2018
Instead of passing along the handle object, just set it as a
property on the stream handle object and let the read handler
grab it from there.

PR-URL: #18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
addaleax added a commit that referenced this pull request Feb 26, 2018
Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean `consume_` flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

PR-URL: #18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
addaleax added a commit that referenced this pull request Feb 26, 2018
Instead of passing along the handle object, just set it as a
property on the stream handle object and let the read handler
grab it from there.

PR-URL: #18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
MylesBorins pushed a commit that referenced this pull request Feb 26, 2018
Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean `consume_` flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

PR-URL: #18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
MylesBorins pushed a commit that referenced this pull request Feb 26, 2018
Instead of passing along the handle object, just set it as a
property on the stream handle object and let the read handler
grab it from there.

PR-URL: #18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@addaleax addaleax mentioned this pull request Feb 27, 2018
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Instead of setting individual callbacks on streams and tracking
stream ownership through a boolean `consume_` flag, always have
one specific listener object in charge of a stream, and call
methods on that object rather than generic C-style callbacks.

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Instead of passing along the handle object, just set it as a
property on the stream handle object and let the read handler
grab it from there.

PR-URL: nodejs#18334
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
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.

8 participants