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

test: http2 rstStream duplicate call #16217

Closed
wants to merge 1 commit into from

Conversation

trivikr
Copy link
Member

@trivikr trivikr commented Oct 15, 2017

This commit fixes an issue with rstStream() which checked incorrect value of rst. It also adds a test case for this fix

if (this[kState].rst) {
// rst has already been called, do not call again,
// skip straight to destroy
stream.destroy();
return;
}

Refs: #14985

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

test, http2

@nodejs-github-bot nodejs-github-bot added dont-land-on-v4.x http2 Issues or PRs related to the http2 subsystem. labels Oct 15, 2017
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.

Looks great! Just a minor nit.

req._destroy = common.mustCall(req._destroy.bind(req), 2);

client.rstStream(req, 0);
// redundant call to rstStream to test rst won't be called again
client.rstStream(req, 0);
Copy link
Member

@apapirovski apapirovski Oct 15, 2017

Choose a reason for hiding this comment

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

If you call the second client.rstStream with a different code, you could then verify that the rstCode didn't get set to the 2nd incorrect code (the strictEqual check below will do the job). Right now it's a bit ambiguous as to whether it does or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've updated the second call to send different code (number 1) which is not updated in req.rstCode

@@ -925,7 +925,7 @@ class Http2Session extends EventEmitter {
'number');
}

if (this[kState].rst) {
if (stream[kState].rst) {
Copy link
Member

Choose a reason for hiding this comment

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

Nice catch!

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks! :-)

This commit fixes an issue with rstStream() which checked incorrect
value of rst. It also adds a test case for this fix

Refs: nodejs#14985
@@ -15,12 +15,15 @@ server.on('listening', common.mustCall(() => {
const client = h2.connect(`http://localhost:${server.address().port}`);

const req = client.request({ ':path': '/' });
// make sure that destroy is called twice
req._destroy = common.mustCall(req._destroy.bind(req), 2);
Copy link
Member

Choose a reason for hiding this comment

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

I am a bit lost in how this is possible, in theory it is protected from running _destroy twice: https://github.com/nodejs/node/blob/master/lib/internal/streams/destroy.js#L10-L30

Copy link
Member Author

@trivikr trivikr Oct 17, 2017

Choose a reason for hiding this comment

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

It was confusing for me too.
The two instances where stream.destroy() is called are:

This might translate to two calls of req._destroy?

I've run the test on repeat 100 times to confirm that it it succeeds using the following command:

> python tools/test.py -J --mode=release parallel/test-http2-client-rststream-before-connect --repeat 100
[00:06|% 100|+ 100|-   0]: Done

Copy link
Member

Choose a reason for hiding this comment

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

I believe @mcollina is right. I think what's happening is that this line is accounting for the 2 triggers of _destroy:

if (this[kID] === undefined) {
debug(`[${sessionName(session[kType])}] queuing destroy for new stream`);
this.once('ready', this._destroy.bind(this, err, callback));
return;
}

The reason that it's different than before is because the declaration was moved before client.rstStream() instead of after. I think that stream.destroy() isn't even necessary and it should just be the empty return;.

ping @jasnell — any thoughts re: whether that stream.destroy() serves an actual purpose?

Copy link
Member

Choose a reason for hiding this comment

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

I've run the test on repeat 100 times

@trivikr the test might be passing, but I'm wondering if the actual behavior is correct.

I don't think that calling rstStream() twice should destroy the stream. It seems a not needed side effect. I think it should throw.

// rst has already been called, do not call again,
// skip straight to destroy
stream.destroy();

cc @jasnell

Copy link
Member Author

@trivikr trivikr Oct 18, 2017

Choose a reason for hiding this comment

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

@mcollina I ran the test on repeat 100 times to check if there's any flakiness in it.
I'll wait for the response from @jasnell and update the code and test as per the recommendation at the end of the discussion.

Copy link
Member

Choose a reason for hiding this comment

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

I'll dig in on this a bit more later on today

@BridgeAR
Copy link
Member

I would argue that this actually is a http2 fix and not a test change. So the http2 subsystem should be used instead.

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.

Just making it explicit this shouldn't land until the _destroy situation is addressed, one way or another.

@trivikr
Copy link
Member Author

trivikr commented Oct 25, 2017

Any update on this request?

@apapirovski
Copy link
Member

Fixed in #16753

@apapirovski apapirovski closed this Nov 7, 2017
@trivikr trivikr deleted the test-http2-client-rststream branch November 7, 2017 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http2 Issues or PRs related to the http2 subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants