Skip to content

Commit a03eedc

Browse files
authored
fix: Pool HTTP connections based on scheme, host, and port (#615)
1 parent 96b95c1 commit a03eedc

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

Sources/ClientRuntime/Networking/Http/CRT/CRTClientEngine.swift

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,31 @@ import Darwin
1212

1313
public class CRTClientEngine: HttpClientEngine {
1414
actor SerialExecutor {
15+
16+
/// Stores the common properties of requests that should share a HTTP connection, such that requests
17+
/// with equal `ConnectionID` values should be pooled together.
18+
///
19+
/// Used as a dictionary key for storing CRT connection managers once they have been created.
20+
/// When a new request is made, a connection manager is reused if it matches the request's scheme,
21+
/// host, and port.
22+
private struct ConnectionPoolID: Hashable {
23+
private let protocolType: ProtocolType?
24+
private let host: String
25+
private let port: Int16
26+
27+
init(endpoint: Endpoint) {
28+
self.protocolType = endpoint.protocolType
29+
self.host = endpoint.host
30+
self.port = endpoint.port
31+
}
32+
}
33+
1534
private var logger: LogAgent
1635

1736
private let windowSize: Int
1837
private let maxConnectionsPerEndpoint: Int
19-
private var connectionPools: [Endpoint: HTTPClientConnectionManager] = [:]
20-
private var http2ConnectionPools: [Endpoint: HTTP2StreamManager] = [:]
38+
private var connectionPools: [ConnectionPoolID: HTTPClientConnectionManager] = [:]
39+
private var http2ConnectionPools: [ConnectionPoolID: HTTP2StreamManager] = [:]
2140
private let sharedDefaultIO = SDKDefaultIO.shared
2241
private let connectTimeoutMs: UInt32?
2342

@@ -29,22 +48,22 @@ public class CRTClientEngine: HttpClientEngine {
2948
}
3049

3150
func getOrCreateConnectionPool(endpoint: Endpoint) throws -> HTTPClientConnectionManager {
32-
guard let connectionPool = connectionPools[endpoint] else {
51+
let poolID = ConnectionPoolID(endpoint: endpoint)
52+
guard let connectionPool = connectionPools[poolID] else {
3353
let newConnectionPool = try createConnectionPool(endpoint: endpoint)
34-
connectionPools[endpoint] = newConnectionPool // save in dictionary
54+
connectionPools[poolID] = newConnectionPool // save in dictionary
3555
return newConnectionPool
3656
}
37-
3857
return connectionPool
3958
}
4059

4160
func getOrCreateHTTP2ConnectionPool(endpoint: Endpoint) throws -> HTTP2StreamManager {
42-
guard let connectionPool = http2ConnectionPools[endpoint] else {
61+
let poolID = ConnectionPoolID(endpoint: endpoint)
62+
guard let connectionPool = http2ConnectionPools[poolID] else {
4363
let newConnectionPool = try createHTTP2ConnectionPool(endpoint: endpoint)
44-
http2ConnectionPools[endpoint] = newConnectionPool // save in dictionary
64+
http2ConnectionPools[poolID] = newConnectionPool // save in dictionary
4565
return newConnectionPool
4666
}
47-
4867
return connectionPool
4968
}
5069

0 commit comments

Comments
 (0)