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

Avoid emitting WINDOW_UPDATE frames when receiving stream closed #233

Merged
merged 1 commit into from
Aug 24, 2020

Conversation

glbrntt
Copy link
Contributor

@glbrntt glbrntt commented Aug 24, 2020

Motivation:

In some cases it's possible for a stream to emit a WINDOW_UPDATE frame
after receiving close from the network. This is unfortunate because in
the eyes of the NIOHTTP2Handler the stream no longer exists which
results in a connection-level error.

Modifications:

  • Add a flag to deliverPendingReads telling it whether it is allowed
    to emit a WINDOW_UPDATE frame
  • Use the above functionality when the stream is closing

Result:

WINDOW_UPDATE frames are no longer emitted from the stream as a result
of delivering pending reads while closing.

@glbrntt glbrntt added the patch-version-bump-only For PRs that when merged will only cause a bump of the patch version, ie. 1.0.x -> 1.0.(x+1) label Aug 24, 2020
@glbrntt glbrntt requested a review from Lukasa August 24, 2020 08:53
Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

I think passing this as a flag doesn't quite work: if for any reason we get a re-entrant call to read0 we'll lose track of the state.

Perhaps this should be state on the InboundWindowManager: we can flip a bit there to say that there is no point sending window update frames anymore. This can then be done in a bunch of places, including when we receive END_STREAM.

Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

Broadly looks good, a quick note on the implementation style.

@@ -67,7 +71,16 @@ struct InboundWindowManager {
return self.calculateWindowIncrement(windowSize: lastWindowSize + self.bufferedBytes)
}

mutating func close() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think the indirection is needed; lets just have closed be an internal property on the window manager and set it directly.

Motivation:

In some cases it's possible for a stream to emit a WINDOW_UPDATE frame
after receiving close from the network. This is unfortunate because in
the eyes of the `NIOHTTP2Handler` the stream no longer exists which
results in a connection-level error.

Modifications:

- Add a `close()` to the `InboundWindowManager`, no new frame sizes will
  be produced if close has been called
- Use the above functionality when the stream is closing and when we
  have seen end stream.

Result:

WINDOW_UPDATE frames are no longer emitted from the stream as a result
of delivering pending reads while closing.
Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

Fantastic, this looks really good.

@Lukasa Lukasa merged commit 1e68e51 into apple:master Aug 24, 2020
@glbrntt glbrntt deleted the gb-no-such-stream branch August 24, 2020 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
patch-version-bump-only For PRs that when merged will only cause a bump of the patch version, ie. 1.0.x -> 1.0.(x+1)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants