Skip to content

Commit 9dbd727

Browse files
committed
Add backpressure configuration
1 parent d13e461 commit 9dbd727

2 files changed

Lines changed: 56 additions & 9 deletions

File tree

Sources/HTTPServer/HTTPServer.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,26 @@ public final class Server<RequestHandler: HTTPServerRequestHandler> {
202202
)
203203
}
204204
}.flatMap {
205-
channel
205+
let asyncChannelConfiguration: NIOAsyncChannel<HTTPRequestPart, HTTPResponsePart>.Configuration
206+
switch configuration.backpressureStrategy.backing {
207+
case .none:
208+
asyncChannelConfiguration = .init(isOutboundHalfClosureEnabled: true)
209+
210+
case .watermark(let low, let high):
211+
asyncChannelConfiguration = .init(
212+
backPressureStrategy: .init(lowWatermark: low, highWatermark: high),
213+
isOutboundHalfClosureEnabled: true
214+
)
215+
}
216+
217+
return channel
206218
.configureAsyncHTTPServerPipeline { channel in
207219
channel.eventLoop.makeCompletedFuture {
208220
try channel.pipeline.syncOperations.addHandler(HTTP1ToHTTPServerCodec(secure: false))
209221

210222
return try NIOAsyncChannel<HTTPRequestPart, HTTPResponsePart>(
211223
wrappingChannelSynchronously: channel,
212-
configuration: .init(isOutboundHalfClosureEnabled: true)
224+
configuration: asyncChannelConfiguration
213225
)
214226
}
215227
} http2ConnectionInitializer: { channel in
@@ -223,7 +235,7 @@ public final class Server<RequestHandler: HTTPServerRequestHandler> {
223235

224236
return try NIOAsyncChannel<HTTPRequestPart, HTTPResponsePart>(
225237
wrappingChannelSynchronously: channel,
226-
configuration: .init(isOutboundHalfClosureEnabled: true)
238+
configuration: asyncChannelConfiguration
227239
)
228240
}
229241
}

Sources/HTTPServer/HTTPServerConfiguration.swift

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ public struct HTTPServerConfiguration: Sendable {
4848

4949
let backing: Backing
5050

51-
public static func insecure() -> Self {
52-
Self(backing: .insecure)
53-
}
51+
public static let insecure: Self = Self(backing: .insecure)
5452

5553
public static func certificateChainAndPrivateKey(
5654
certificateChain: [Certificate],
@@ -64,17 +62,54 @@ public struct HTTPServerConfiguration: Sendable {
6462
)
6563
}
6664
}
65+
66+
/// Configuration for the backpressure strategy to use when reading requests and writing back responses.
67+
public struct BackPressureStrategy: Sendable {
68+
enum Backing {
69+
case none
70+
case watermark(low: Int, high: Int)
71+
}
72+
73+
internal let backing: Backing
74+
75+
private init(backing: Backing) {
76+
self.backing = backing
77+
}
78+
79+
/// No backpressure will be applied to reading requests or writing responses.
80+
public static let none: Self = .init(backing: .none)
81+
82+
/// A low/high watermark will be applied when reading requests and writing responses.
83+
/// - Parameters:
84+
/// - low: The threshold below which the consumer will ask the producer to produce more elements.
85+
/// - high: The threshold above which the producer will stop producing elements.
86+
/// - Returns: A low/high watermark strategy with the configured thresholds.
87+
public static func watermark(low: Int, high: Int) -> Self {
88+
.init(backing: .watermark(low: low, high: high))
89+
}
90+
}
6791

6892
/// Network binding configuration
6993
public var bindTarget: BindTarget
70-
94+
95+
/// TLS configuration for the server.
7196
public var tlSConfiguration: TLSConfiguration
72-
97+
98+
/// Backpressure strategy to use in the server.
99+
public var backpressureStrategy: BackPressureStrategy
100+
101+
/// Create a new configuration.
102+
/// - Parameters:
103+
/// - bindTarget: A ``BindTarget``.
104+
/// - tlsConfiguration: A ``TLSConfiguration``. Defaults to ``TLSConfiguration/insecure``.
105+
/// - backpressureStrategy: A ``BackPressureStrategy``. Defaults to ``BackPressureStrategy/none``.
73106
public init(
74107
bindTarget: BindTarget,
75-
tlsConfiguration: TLSConfiguration = .insecure()
108+
tlsConfiguration: TLSConfiguration = .insecure,
109+
backpressureStrategy: BackPressureStrategy = .none
76110
) {
77111
self.bindTarget = bindTarget
78112
self.tlSConfiguration = tlsConfiguration
113+
self.backpressureStrategy = backpressureStrategy
79114
}
80115
}

0 commit comments

Comments
 (0)