Skip to content

Conversation

@Lukasa
Copy link
Contributor

@Lukasa Lukasa commented Aug 6, 2018

Motivation:

Long-lived connections that have many inactive streams would cause
crashes. Crashes are, in my professional opinion, less than ideal
when they occur under expected usage cases.

Modifications:

  • Fixed an inverted boolean check that would discard only active
    streams.
  • Added tests.

Result:

Fewer crashes, better software.

private mutating func purgeOldStreams() {
while self.streamMap.count >= maxSize {
let lowestStreamID = self.streamMap.filter { $0.value.active }.keys.sorted().first { $0 != 0 && $0 != Int32.max }!
let lowestStreamID = self.streamMap.filter { !$0.value.active }.keys.sorted().first { $0 != 0 && $0 != Int32.max }!
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the actual fix: I just tackled a TODO while I was here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I assume the filtered array (and, by extension, self.streamMap) will now never be empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not quite, but I wanted to separate the other issue out into another patch.

The TL;DR there is that if the sum of both sides SETTINGS_MAX_CONCURRENT_STREAMS is higher than maxSize, and there are actually more than maxSides valid open active streams, then we'll explode again. That can be fixed by changing the loop conditional above to move the filter out of the loop so that we only care if there are too many closed streams.

This will all get a bit better when we land #10 and the follow-on framing logic such that I can start work on replacing the nghttp2 state machine. At that stage we'll have a much more complete insight into the connection state and won't have to use this somewhat insane purging construction.

Copy link
Member

@weissi weissi left a comment

Choose a reason for hiding this comment

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

submitting because page changed

self.session = NGHTTP2Session(mode: self.mode,
allocator: ctx.channel.allocator,
maxCachedStreamIDs: 1024, // TODO(cory): Make configurable
maxCachedStreamIDs: self.maxCachedClosedStreams, // TODO(cory): Make configurable
Copy link
Member

Choose a reason for hiding this comment

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

well, it's now configurable so the comment can go right? Or did you mean ChannelOption kind of configurable?

Copy link
Member

@weissi weissi left a comment

Choose a reason for hiding this comment

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

thanks! looks really good! Just nits

let maxCachedClosedStreams = 1024

// Begin by getting the connection up.
try self.basicHTTP2Connection(maxCachedClosedStreams: 1024)
Copy link
Member

Choose a reason for hiding this comment

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

use the maxCachedClosedStreams variable here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

let maxCachedClosedStreams = 1024

// Begin by getting the connection up.
try self.basicHTTP2Connection(maxCachedClosedStreams: 1024)
Copy link
Member

Choose a reason for hiding this comment

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

and here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Contributor

@MrMage MrMage left a comment

Choose a reason for hiding this comment

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

Just a few drive-by comments, sorry ;-)

let maxCachedClosedStreams = 1024

// Begin by getting the connection up.
try self.basicHTTP2Connection(maxCachedClosedStreams: maxCachedClosedStreams)
Copy link
Contributor

Choose a reason for hiding this comment

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

I was about to mention the following (first part is already fixed): As you are declaring maxCachedClosedStreams above, should you replace 1024 with maxCachedClosedStreams here? Also, would it make sense to pick a lower value than 1024 for faster test runtime?

try self.assertFramesRoundTrip(frames: [respFrame], sender: self.serverChannel, receiver: self.clientChannel)
}

// Ok, now we're going to open *two* streams. In the old, broken code, the opening of the second
Copy link
Contributor

Choose a reason for hiding this comment

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

Mention this PR to more easily reference what the broken code was?

Motivation:

Long-lived connections that have many inactive streams would cause
crashes. Crashes are, in my professional opinion, less than ideal
when they occur under expected usage cases.

Modifications:

- Fixed an inverted boolean check that would discard only *active*
  streams.
- Made the cached stream count configurable, removing a TODO.
- Added tests.

Result:

Fewer crashes, better software.
@Lukasa
Copy link
Contributor Author

Lukasa commented Aug 6, 2018

No need to apologise @MrMage, more code review is always valuable. I've addressed both your comments.

@Lukasa
Copy link
Contributor Author

Lukasa commented Aug 8, 2018

@weissi Want to re-review?

@bmhatfield
Copy link

(I'm just a bystander, but) Bump: @weissi this PR fixes an issue discovered in grpc/grpc-swift#281 - just adding a friendly bump for a re-review here :-)

Copy link
Member

@weissi weissi left a comment

Choose a reason for hiding this comment

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

sorry for the delay! thanks @bmhatfield for the reminder

@weissi weissi merged commit b7085b6 into apple:master Aug 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants