-
Notifications
You must be signed in to change notification settings - Fork 428
Make HTTP/2 flow control window size configurable for clients and servers #786
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
Make HTTP/2 flow control window size configurable for clients and servers #786
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broadly I think this looks really good! We should aim to get a HTTP/2 release out early this week that can unblock this PR.
@@ -31,6 +31,7 @@ extension ClientConnection { | |||
extension ClientConnection { | |||
public class Builder { | |||
private let group: EventLoopGroup | |||
private var targetWindowSize: Int = 65535 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Lukasa should we add a default-target-window-size constant to nio-http2? This is floating around in a number of places.
Alternatively we could just switch the value in the gRPC API to be an optional/enum with "defer to http2" and "use this value" cases.
That's the right place 👍 |
@johnkassebaum FYI your NIO HTTP/2 change was tagged a little while ago |
Thanks @glbrntt I saw that. So sorry for the delay on this, was able to get back to it last night and will address comments and add server configuration today. |
8246629
to
65b42eb
Compare
65b42eb
to
5be66d8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem about the delay @johnkassebaum! This basically looks good, I just have a couple of comments around docs/naming.
Sources/GRPC/ClientConnection.swift
Outdated
@@ -324,6 +330,7 @@ extension Channel { | |||
} | |||
|
|||
func configureGRPCClient( | |||
httpTargetWindowSize: Int = 65535, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need a default here: we should have always have a value from the configuration.
@@ -195,6 +197,15 @@ extension ClientConnection.Builder.Secure { | |||
} | |||
} | |||
|
|||
extension ClientConnection.Builder { | |||
/// Sets the HTTP/2 flow control target window size. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Sets the HTTP/2 flow control target window size. | |
/// Sets the HTTP/2 flow control target window size. Defaults to 65,535 if not explicitly set. |
gRPC-Swift.podspec
Outdated
@@ -18,7 +18,7 @@ Pod::Spec.new do |s| | |||
|
|||
s.dependency 'Logging', '1.2.0' | |||
s.dependency 'SwiftNIO', '2.15.0' | |||
s.dependency 'SwiftNIOHTTP2', '1.11.0' | |||
s.dependency 'SwiftNIOHTTP2', '1.12.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to update this; it's a generated file.
@@ -135,6 +149,43 @@ class ClientTLSFailureTests: GRPCTestCase { | |||
XCTFail("Expected NIOSSLError.handshakeFailed(BoringSSL.sslError)") | |||
} | |||
} | |||
|
|||
func testClientConnectionFailsWhenServerIsUnknownWithHTTPTargetWindowSize() throws { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove the extra tests since we're not actually validating a change in behaviour here? I think I'm okay just deferring to NIO HTTP/2 for the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No further notes beyond @glbrntt's.
Package.swift
Outdated
@@ -29,7 +29,7 @@ let package = Package( | |||
// Main SwiftNIO package | |||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.14.0"), | |||
// HTTP2 via SwiftNIO | |||
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.8.0"), | |||
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.12.0"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind bumping this to 1.12.1
? We missed something the first time with the window size: apple/swift-nio-http2#205
…connection. Motivation: Higher stremaing thruput from server to client is available by specifying a flow control window size higher than the initial value of 2^16-1. The target value needs to be passed either using SETTINGS_INITIAL_WINDOW_SIZE in the connection preface, or via a WINDOW_UPDATE. The HTTP2FlowControlWindow passes the value configured here in `windowUpdate`. Modifications: Set package and podspec dependency swift-nio-http2 target to 1.12.0, needed for pipeline configuration with http/2 flow control target window size coniguration. Added property `httpTargetWindowSize` to `ClientConnection.Configuration`. In `ClientConnection.Configuration.init`, added httpTargetWindowSize arg with default value 2^16-1. Added property and setter for `httpTargetWindowSize` to `ClientConnection.Builder`. During client bootstrap in ConnectionManager, pass `configuration.httpTargetWindowSize` to the channel configurator. Configure http/2 flow control target window size on the grpc client pipeline. Duplicated all tests that directly invoke the original `ClientConnection.Configuration.init` to explicitly pass `httpTargetWindowSize` to the new initializer. Result: One can build a `ClientConnection` with a http/2 flow control target window size value that is configured via a WINDOW_UPDATE after the connection is established.
…connection. Motivation: Higher streaming thruput from client to server is available by specifying a flow control window size higher than the initial value of 2^16-1. The target value needs to be passed either using SETTINGS_INITIAL_WINDOW_SIZE in the connection preface, or via a WINDOW_UPDATE. The HTTP2FlowControlWindow passes the value configured here in `windowUpdate`. Modifications: Added property `httpTargetWindowSize` to `Server.Configuration`. In `Server.Configuration.init`, added httpTargetWindowSize arg with default value 2^16-1. Added property and setter for `httpTargetWindowSize` to `Server.Builder`. During server bootstrap in Server.start, pass `configuration.httpTargetWindowSize` to the HTTPProtocolSwitcher. Configure http/2 flow control target window size on the http2 pipeline in HTTPProxySwitcher. Result: One can build a `Server` with a target window size value that is configured via a WINDOW_UPDATE after the connection is established.
5be66d8
to
c80bd97
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks @johnkassebaum!
Make HTTP/2 flow control target window size configurable in a client or server HTTP2 connection.
Motivation:
Higher streaming thruput between server and client is available by the either specifying a HTTP/2 flow control window size higher than the initial value of 2^16-1. The target value needs to be passed either using
SETTINGS_INITIAL_WINDOW_SIZE
in the connection preface, or via aWINDOW_UPDATE
. As implemented here, theHTTP2FlowControlWindow
passes the value configured in awindowUpdate
.Modifications:
For the client:
Added property
targetWindowSize
toClientConnection.Configuration
.In the existing
ClientConnection.Configuration.init
, sets the newtargetWindowSize
property to the initial flow-control window size (65535).Duplicated
ClientConnection.Configuration.init
and added atargetWindowSize
arg.Added property and setter for
targetWindowSize
toClientConnection.Builder
.During client bootstrap, pass
configuration.targetWindowSize
to the channel initializer.Duplicated channel initializer
configureGRPCClient
and added atargetWindowSize
arg.Duplicated all tests that directly invoke the original
ClientConnection.Configuration.init
to explicitly passtargetWindowSize
to the new initializer.For the server:
Added property
httpTargetWindowSize
toServer.Configuration
.In
Server.Configuration.init
, added httpTargetWindowSize arg with default value 2^16-1.Added property and setter for
httpTargetWindowSize
toServer.Builder
.During server bootstrap in
Server.start
, passconfiguration.httpTargetWindowSize
to theHTTPProtocolSwitcher
.Configure http/2 flow control target window size on the http2 pipeline in
HTTPProxySwitcher
.Result:
One can build a
ClientConnection
orServer
with a target window size value that is configured via a WINDOW_UPDATE after the connection is established.