Explorar el Código

Expose max reset streams HTTP2 configuration (#2226)

We have exposed the max reset stream frames config in NIO H2
(https://github.com/apple/swift-nio-http2/pull/494/) - we need to add
configuration to expose it in gRPC v1 as well.
Gus Cairo hace 8 meses
padre
commit
b4156752ab

+ 1 - 1
Package.swift

@@ -36,7 +36,7 @@ let packageDependencies: [Package.Dependency] = [
   ),
   .package(
     url: "https://github.com/apple/swift-nio-http2.git",
-    from: "1.32.0"
+    from: "1.36.0"
   ),
   .package(
     url: "https://github.com/apple/swift-nio-transport-services.git",

+ 12 - 2
Sources/GRPC/ClientConnection.swift

@@ -457,6 +457,13 @@ extension ClientConnection {
       }
     }
 
+    /// The HTTP/2 max number of reset streams. Defaults to 32. Must be non-negative.
+    public var httpMaxResetStreams: Int = 32 {
+      willSet {
+        precondition(newValue >= 0, "httpMaxResetStreams must be non-negative")
+      }
+    }
+
     /// A logger for background information (such as connectivity state). A separate logger for
     /// requests may be provided in the `CallOptions`.
     ///
@@ -630,10 +637,12 @@ extension ChannelPipeline.SynchronousOperations {
     connectionIdleTimeout: TimeAmount,
     httpTargetWindowSize: Int,
     httpMaxFrameSize: Int,
+    httpMaxResetStreams: Int,
     errorDelegate: ClientErrorDelegate?,
     logger: Logger
   ) throws {
-    let initialSettings = [
+    var configuration = NIOHTTP2Handler.ConnectionConfiguration()
+    configuration.initialSettings = [
       // As per the default settings for swift-nio-http2:
       HTTP2Setting(parameter: .maxHeaderListSize, value: HPACKDecoder.defaultMaxHeaderListSize),
       // We never expect (or allow) server initiated streams.
@@ -642,10 +651,11 @@ extension ChannelPipeline.SynchronousOperations {
       HTTP2Setting(parameter: .maxFrameSize, value: httpMaxFrameSize),
       HTTP2Setting(parameter: .initialWindowSize, value: httpTargetWindowSize),
     ]
+    configuration.maximumRecentlyResetStreams = httpMaxResetStreams
 
     // We could use 'configureHTTP2Pipeline' here, but we need to add a few handlers between the
     // two HTTP/2 handlers so we'll do it manually instead.
-    try self.addHandler(NIOHTTP2Handler(mode: .client, initialSettings: initialSettings))
+    try self.addHandler(NIOHTTP2Handler(mode: .client, connectionConfiguration: configuration))
 
     let h2Multiplexer = HTTP2StreamMultiplexer(
       mode: .client,

+ 8 - 0
Sources/GRPC/ConnectionManagerChannelProvider.swift

@@ -70,6 +70,8 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
   internal var httpTargetWindowSize: Int
   @usableFromInline
   internal var httpMaxFrameSize: Int
+  @usableFromInline
+  internal var httpMaxResetStreams: Int
 
   @usableFromInline
   internal var errorDelegate: Optional<ClientErrorDelegate>
@@ -102,6 +104,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
     tlsConfiguration: GRPCTLSConfiguration?,
     httpTargetWindowSize: Int,
     httpMaxFrameSize: Int,
+    httpMaxResetStreams: Int,
     errorDelegate: ClientErrorDelegate?,
     debugChannelInitializer: ((Channel) -> EventLoopFuture<Void>)?,
     nwParametersConfigurator: (@Sendable (NWParameters) -> Void)?
@@ -114,6 +117,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
       tlsConfiguration: tlsConfiguration,
       httpTargetWindowSize: httpTargetWindowSize,
       httpMaxFrameSize: httpMaxFrameSize,
+      httpMaxResetStreams: httpMaxResetStreams,
       errorDelegate: errorDelegate,
       debugChannelInitializer: debugChannelInitializer
     )
@@ -131,6 +135,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
     tlsConfiguration: GRPCTLSConfiguration?,
     httpTargetWindowSize: Int,
     httpMaxFrameSize: Int,
+    httpMaxResetStreams: Int,
     errorDelegate: ClientErrorDelegate?,
     debugChannelInitializer: ((Channel) -> EventLoopFuture<Void>)?
   ) {
@@ -143,6 +148,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
 
     self.httpTargetWindowSize = httpTargetWindowSize
     self.httpMaxFrameSize = httpMaxFrameSize
+    self.httpMaxResetStreams = httpMaxResetStreams
 
     self.errorDelegate = errorDelegate
     self.debugChannelInitializer = debugChannelInitializer
@@ -180,6 +186,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
       tlsConfiguration: configuration.tlsConfiguration,
       httpTargetWindowSize: configuration.httpTargetWindowSize,
       httpMaxFrameSize: configuration.httpMaxFrameSize,
+      httpMaxResetStreams: configuration.httpMaxResetStreams,
       errorDelegate: configuration.errorDelegate,
       debugChannelInitializer: configuration.debugChannelInitializer
     )
@@ -259,6 +266,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
             connectionIdleTimeout: self.connectionIdleTimeout,
             httpTargetWindowSize: self.httpTargetWindowSize,
             httpMaxFrameSize: self.httpMaxFrameSize,
+            httpMaxResetStreams: self.httpMaxResetStreams,
             errorDelegate: self.errorDelegate,
             logger: logger
           )

+ 7 - 0
Sources/GRPC/ConnectionPool/GRPCChannelPool.swift

@@ -261,6 +261,13 @@ extension GRPCChannelPool.Configuration {
         self.maxFrameSize = self.maxFrameSize.clamped(to: Self.allowedMaxFrameSizes)
       }
     }
+
+    /// The HTTP/2 max number of reset streams. Defaults to 32. Must be non-negative.
+    public var maxResetStreams: Int = 32 {
+      willSet {
+        precondition(newValue >= 0, "maxResetStreams must be non-negative")
+      }
+    }
   }
 }
 

+ 3 - 0
Sources/GRPC/ConnectionPool/PooledChannel.swift

@@ -90,6 +90,7 @@ internal final class PooledChannel: GRPCChannel {
         tlsConfiguration: configuration.transportSecurity.tlsConfiguration,
         httpTargetWindowSize: configuration.http2.targetWindowSize,
         httpMaxFrameSize: configuration.http2.maxFrameSize,
+        httpMaxResetStreams: configuration.http2.maxResetStreams,
         errorDelegate: configuration.errorDelegate,
         debugChannelInitializer: configuration.debugChannelInitializer,
         nwParametersConfigurator: configuration.transportServices.nwParametersConfigurator
@@ -103,6 +104,7 @@ internal final class PooledChannel: GRPCChannel {
         tlsConfiguration: configuration.transportSecurity.tlsConfiguration,
         httpTargetWindowSize: configuration.http2.targetWindowSize,
         httpMaxFrameSize: configuration.http2.maxFrameSize,
+        httpMaxResetStreams: configuration.http2.maxResetStreams,
         errorDelegate: configuration.errorDelegate,
         debugChannelInitializer: configuration.debugChannelInitializer
       )
@@ -116,6 +118,7 @@ internal final class PooledChannel: GRPCChannel {
       tlsConfiguration: configuration.transportSecurity.tlsConfiguration,
       httpTargetWindowSize: configuration.http2.targetWindowSize,
       httpMaxFrameSize: configuration.http2.maxFrameSize,
+      httpMaxResetStreams: configuration.http2.maxResetStreams,
       errorDelegate: configuration.errorDelegate,
       debugChannelInitializer: configuration.debugChannelInitializer
     )

+ 21 - 21
Sources/GRPC/GRPCServerPipelineConfigurator.swift

@@ -79,27 +79,27 @@ final class GRPCServerPipelineConfigurator: ChannelInboundHandler, RemovableChan
 
   /// Makes an HTTP/2 handler.
   private func makeHTTP2Handler() -> NIOHTTP2Handler {
-    return .init(
-      mode: .server,
-      initialSettings: [
-        HTTP2Setting(
-          parameter: .maxConcurrentStreams,
-          value: self.configuration.httpMaxConcurrentStreams
-        ),
-        HTTP2Setting(
-          parameter: .maxHeaderListSize,
-          value: HPACKDecoder.defaultMaxHeaderListSize
-        ),
-        HTTP2Setting(
-          parameter: .maxFrameSize,
-          value: self.configuration.httpMaxFrameSize
-        ),
-        HTTP2Setting(
-          parameter: .initialWindowSize,
-          value: self.configuration.httpTargetWindowSize
-        ),
-      ]
-    )
+    var configuration = NIOHTTP2Handler.ConnectionConfiguration()
+    configuration.initialSettings = [
+      HTTP2Setting(
+        parameter: .maxConcurrentStreams,
+        value: self.configuration.httpMaxConcurrentStreams
+      ),
+      HTTP2Setting(
+        parameter: .maxHeaderListSize,
+        value: HPACKDecoder.defaultMaxHeaderListSize
+      ),
+      HTTP2Setting(
+        parameter: .maxFrameSize,
+        value: self.configuration.httpMaxFrameSize
+      ),
+      HTTP2Setting(
+        parameter: .initialWindowSize,
+        value: self.configuration.httpTargetWindowSize
+      ),
+    ]
+    configuration.maximumRecentlyResetStreams = self.configuration.httpMaxResetStreams
+    return NIOHTTP2Handler(mode: .server, connectionConfiguration: configuration)
   }
 
   /// Makes an HTTP/2 multiplexer suitable handling gRPC requests.

+ 7 - 0
Sources/GRPC/Server.swift

@@ -379,6 +379,13 @@ extension Server {
       }
     }
 
+    /// The HTTP/2 max number of reset streams. Defaults to 32. Must be non-negative.
+    public var httpMaxResetStreams: Int = 32 {
+      willSet {
+        precondition(newValue >= 0, "httpMaxResetStreams must be non-negative")
+      }
+    }
+
     /// The root server logger. Accepted connections will branch from this logger and RPCs on
     /// each connection will use a logger branched from the connections logger. This logger is made
     /// available to service providers via `context`. Defaults to a no-op logger.