Skip to content

Commit 6d5ff3c

Browse files
authored
Merge branch 'release/1.x' into bugfix/method-name
2 parents df9b141 + 07616fd commit 6d5ff3c

12 files changed

+438
-61
lines changed

.github/workflows/ci.yaml

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
name: License Header and Formatting Checks
1010
runs-on: ubuntu-latest
1111
container:
12-
image: swift:6.0-jammy
12+
image: swift:6.1
1313
steps:
1414
- name: "Checkout repository"
1515
uses: actions/checkout@v4
@@ -25,18 +25,9 @@ jobs:
2525
fail-fast: false
2626
matrix:
2727
include:
28-
- image: swiftlang/swift:nightly-jammy
29-
# No TSAN because of: https://github.com/apple/swift/issues/59068
30-
# swift-test-flags: "--sanitize=thread"
28+
- image: swift:6.1
3129
- image: swift:6.0-jammy
32-
# No TSAN because of: https://github.com/apple/swift/issues/59068
33-
# swift-test-flags: "--sanitize=thread"
3430
- image: swift:5.10.1-noble
35-
# No TSAN because of: https://github.com/apple/swift/issues/59068
36-
# swift-test-flags: "--sanitize=thread"
37-
- image: swift:5.9-jammy
38-
# No TSAN because of: https://github.com/apple/swift/issues/59068
39-
# swift-test-flags: "--sanitize=thread"
4031
name: Build and Test on ${{ matrix.image }}
4132
runs-on: ubuntu-latest
4233
container:
@@ -54,8 +45,8 @@ jobs:
5445
fail-fast: false
5546
matrix:
5647
include:
57-
- image: swiftlang/swift:nightly-jammy
58-
swift-version: 'main'
48+
- image: swift:6.1
49+
swift-version: '6.1'
5950
env:
6051
MAX_ALLOCS_ALLOWED_bidi_1k_rpcs_10_requests: 323000
6152
MAX_ALLOCS_ALLOWED_bidi_1k_rpcs_1_request: 161000
@@ -87,17 +78,6 @@ jobs:
8778
MAX_ALLOCS_ALLOWED_unary_1k_ping_pong: 163000
8879
MAX_ALLOCS_ALLOWED_unary_1k_ping_pong_interceptors_client: 170000
8980
MAX_ALLOCS_ALLOWED_unary_1k_ping_pong_interceptors_server: 170000
90-
- image: swift:5.9-jammy
91-
swift-version: 5.9
92-
env:
93-
MAX_ALLOCS_ALLOWED_bidi_1k_rpcs_10_requests: 323000
94-
MAX_ALLOCS_ALLOWED_bidi_1k_rpcs_1_request: 161000
95-
MAX_ALLOCS_ALLOWED_embedded_server_bidi_1k_rpcs_10_small_requests: 110000
96-
MAX_ALLOCS_ALLOWED_embedded_server_bidi_1k_rpcs_1_small_request: 65000
97-
MAX_ALLOCS_ALLOWED_embedded_server_unary_1k_rpcs_1_small_request: 61000
98-
MAX_ALLOCS_ALLOWED_unary_1k_ping_pong: 163000
99-
MAX_ALLOCS_ALLOWED_unary_1k_ping_pong_interceptors_client: 170000
100-
MAX_ALLOCS_ALLOWED_unary_1k_ping_pong_interceptors_server: 170000
10181
name: Performance Tests on ${{ matrix.image }}
10282
runs-on: ubuntu-latest
10383
container:
@@ -113,14 +93,12 @@ jobs:
11393
fail-fast: false
11494
matrix:
11595
include:
116-
- image: swiftlang/swift:nightly-jammy
117-
swift-tools-version: '6.0'
96+
- image: swift:6.1
97+
swift-tools-version: '6.1'
11898
- image: swift:6.0-jammy
11999
swift-tools-version: '6.0'
120100
- image: swift:5.10.1-noble
121101
swift-tools-version: '5.10'
122-
- image: swift:5.9-jammy
123-
swift-tools-version: '5.9'
124102
name: Integration Tests on ${{ matrix.image }}
125103
runs-on: ubuntu-latest
126104
container:

Package.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.9
1+
// swift-tools-version:5.10
22
/*
33
* Copyright 2017, gRPC Authors All rights reserved.
44
*
@@ -36,11 +36,11 @@ let packageDependencies: [Package.Dependency] = [
3636
),
3737
.package(
3838
url: "https://github.com/apple/swift-nio-http2.git",
39-
from: "1.32.0"
39+
from: "1.36.0"
4040
),
4141
.package(
4242
url: "https://github.com/apple/swift-nio-transport-services.git",
43-
from: "1.15.0"
43+
from: "1.24.0"
4444
),
4545
.package(
4646
url: "https://github.com/apple/swift-nio-extras.git",

Sources/GRPC/ClientConnection.swift

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ import Foundation
3333
import NIOSSL
3434
#endif
3535

36+
#if canImport(Network)
37+
import Network
38+
#endif
39+
3640
/// Provides a single, managed connection to a server which is guaranteed to always use the same
3741
/// `EventLoop`.
3842
///
@@ -453,6 +457,13 @@ extension ClientConnection {
453457
}
454458
}
455459

460+
/// The HTTP/2 max number of reset streams. Defaults to 32. Must be non-negative.
461+
public var httpMaxResetStreams: Int = 32 {
462+
willSet {
463+
precondition(newValue >= 0, "httpMaxResetStreams must be non-negative")
464+
}
465+
}
466+
456467
/// A logger for background information (such as connectivity state). A separate logger for
457468
/// requests may be provided in the `CallOptions`.
458469
///
@@ -469,6 +480,21 @@ extension ClientConnection {
469480
@preconcurrency
470481
public var debugChannelInitializer: (@Sendable (Channel) -> EventLoopFuture<Void>)?
471482

483+
#if canImport(Network)
484+
/// A closure allowing to customise the `NWParameters` used when establishing a connection using `NIOTransportServices`.
485+
@available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *)
486+
public var nwParametersConfigurator: (@Sendable (NWParameters) -> Void)? {
487+
get {
488+
self._nwParametersConfigurator as! (@Sendable (NWParameters) -> Void)?
489+
}
490+
set {
491+
self._nwParametersConfigurator = newValue
492+
}
493+
}
494+
495+
private var _nwParametersConfigurator: (any Sendable)?
496+
#endif
497+
472498
#if canImport(NIOSSL)
473499
/// Create a `Configuration` with some pre-defined defaults. Prefer using
474500
/// `ClientConnection.secure(group:)` to build a connection secured with TLS or
@@ -611,10 +637,12 @@ extension ChannelPipeline.SynchronousOperations {
611637
connectionIdleTimeout: TimeAmount,
612638
httpTargetWindowSize: Int,
613639
httpMaxFrameSize: Int,
640+
httpMaxResetStreams: Int,
614641
errorDelegate: ClientErrorDelegate?,
615642
logger: Logger
616643
) throws {
617-
let initialSettings = [
644+
var configuration = NIOHTTP2Handler.ConnectionConfiguration()
645+
configuration.initialSettings = [
618646
// As per the default settings for swift-nio-http2:
619647
HTTP2Setting(parameter: .maxHeaderListSize, value: HPACKDecoder.defaultMaxHeaderListSize),
620648
// We never expect (or allow) server initiated streams.
@@ -623,10 +651,11 @@ extension ChannelPipeline.SynchronousOperations {
623651
HTTP2Setting(parameter: .maxFrameSize, value: httpMaxFrameSize),
624652
HTTP2Setting(parameter: .initialWindowSize, value: httpTargetWindowSize),
625653
]
654+
configuration.maximumRecentlyResetStreams = httpMaxResetStreams
626655

627656
// We could use 'configureHTTP2Pipeline' here, but we need to add a few handlers between the
628657
// two HTTP/2 handlers so we'll do it manually instead.
629-
try self.addHandler(NIOHTTP2Handler(mode: .client, initialSettings: initialSettings))
658+
try self.addHandler(NIOHTTP2Handler(mode: .client, connectionConfiguration: configuration))
630659

631660
let h2Multiplexer = HTTP2StreamMultiplexer(
632661
mode: .client,

Sources/GRPC/ConnectionManagerChannelProvider.swift

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import NIOTransportServices
2222
import NIOSSL
2323
#endif
2424

25+
#if canImport(Network)
26+
import Network
27+
#endif
28+
2529
@usableFromInline
2630
internal protocol ConnectionManagerChannelProvider {
2731
/// Make an `EventLoopFuture<Channel>`.
@@ -66,12 +70,62 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
6670
internal var httpTargetWindowSize: Int
6771
@usableFromInline
6872
internal var httpMaxFrameSize: Int
73+
@usableFromInline
74+
internal var httpMaxResetStreams: Int
6975

7076
@usableFromInline
7177
internal var errorDelegate: Optional<ClientErrorDelegate>
7278
@usableFromInline
7379
internal var debugChannelInitializer: Optional<(Channel) -> EventLoopFuture<Void>>
7480

81+
#if canImport(Network)
82+
@available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *)
83+
@usableFromInline
84+
internal var nwParametersConfigurator: (@Sendable (NWParameters) -> Void)? {
85+
get {
86+
self._nwParametersConfigurator as! (@Sendable (NWParameters) -> Void)?
87+
}
88+
set {
89+
self._nwParametersConfigurator = newValue
90+
}
91+
}
92+
93+
private var _nwParametersConfigurator: (any Sendable)?
94+
#endif
95+
96+
#if canImport(Network)
97+
@inlinable
98+
@available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *)
99+
internal init(
100+
connectionTarget: ConnectionTarget,
101+
connectionKeepalive: ClientConnectionKeepalive,
102+
connectionIdleTimeout: TimeAmount,
103+
tlsMode: TLSMode,
104+
tlsConfiguration: GRPCTLSConfiguration?,
105+
httpTargetWindowSize: Int,
106+
httpMaxFrameSize: Int,
107+
httpMaxResetStreams: Int,
108+
errorDelegate: ClientErrorDelegate?,
109+
debugChannelInitializer: ((Channel) -> EventLoopFuture<Void>)?,
110+
nwParametersConfigurator: (@Sendable (NWParameters) -> Void)?
111+
) {
112+
self.init(
113+
connectionTarget: connectionTarget,
114+
connectionKeepalive: connectionKeepalive,
115+
connectionIdleTimeout: connectionIdleTimeout,
116+
tlsMode: tlsMode,
117+
tlsConfiguration: tlsConfiguration,
118+
httpTargetWindowSize: httpTargetWindowSize,
119+
httpMaxFrameSize: httpMaxFrameSize,
120+
httpMaxResetStreams: httpMaxResetStreams,
121+
errorDelegate: errorDelegate,
122+
debugChannelInitializer: debugChannelInitializer
123+
)
124+
125+
self.nwParametersConfigurator = nwParametersConfigurator
126+
}
127+
#endif
128+
75129
@inlinable
76130
internal init(
77131
connectionTarget: ConnectionTarget,
@@ -81,6 +135,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
81135
tlsConfiguration: GRPCTLSConfiguration?,
82136
httpTargetWindowSize: Int,
83137
httpMaxFrameSize: Int,
138+
httpMaxResetStreams: Int,
84139
errorDelegate: ClientErrorDelegate?,
85140
debugChannelInitializer: ((Channel) -> EventLoopFuture<Void>)?
86141
) {
@@ -93,6 +148,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
93148

94149
self.httpTargetWindowSize = httpTargetWindowSize
95150
self.httpMaxFrameSize = httpMaxFrameSize
151+
self.httpMaxResetStreams = httpMaxResetStreams
96152

97153
self.errorDelegate = errorDelegate
98154
self.debugChannelInitializer = debugChannelInitializer
@@ -130,9 +186,16 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
130186
tlsConfiguration: configuration.tlsConfiguration,
131187
httpTargetWindowSize: configuration.httpTargetWindowSize,
132188
httpMaxFrameSize: configuration.httpMaxFrameSize,
189+
httpMaxResetStreams: configuration.httpMaxResetStreams,
133190
errorDelegate: configuration.errorDelegate,
134191
debugChannelInitializer: configuration.debugChannelInitializer
135192
)
193+
194+
#if canImport(Network)
195+
if #available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) {
196+
self.nwParametersConfigurator = configuration.nwParametersConfigurator
197+
}
198+
#endif
136199
}
137200

138201
private var serverHostname: String? {
@@ -203,6 +266,7 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
203266
connectionIdleTimeout: self.connectionIdleTimeout,
204267
httpTargetWindowSize: self.httpTargetWindowSize,
205268
httpMaxFrameSize: self.httpMaxFrameSize,
269+
httpMaxResetStreams: self.httpMaxResetStreams,
206270
errorDelegate: self.errorDelegate,
207271
logger: logger
208272
)
@@ -222,6 +286,15 @@ internal struct DefaultChannelProvider: ConnectionManagerChannelProvider {
222286
_ = bootstrap.connectTimeout(connectTimeout)
223287
}
224288

289+
#if canImport(Network)
290+
if #available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *),
291+
let configurator = self.nwParametersConfigurator,
292+
let transportServicesBootstrap = bootstrap as? NIOTSConnectionBootstrap
293+
{
294+
_ = transportServicesBootstrap.configureNWParameters(configurator)
295+
}
296+
#endif
297+
225298
return bootstrap.connect(to: self.connectionTarget)
226299
}
227300
}

Sources/GRPC/ConnectionPool/GRPCChannelPool.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import NIOPosix
1919

2020
import struct Foundation.UUID
2121

22+
#if canImport(Network)
23+
import Network
24+
#endif
25+
2226
public enum GRPCChannelPool {
2327
/// Make a new ``GRPCChannel`` on which calls may be made to gRPC services.
2428
///
@@ -191,6 +195,12 @@ extension GRPCChannelPool {
191195
return SwiftLogNoOpLogHandler()
192196
}
193197
)
198+
199+
#if canImport(Network)
200+
/// `TransportServices` related configuration. This will be ignored unless an appropriate event loop group
201+
/// (e.g. `NIOTSEventLoopGroup`) is used.
202+
public var transportServices: TransportServices = .defaults
203+
#endif
194204
}
195205
}
196206

@@ -251,6 +261,13 @@ extension GRPCChannelPool.Configuration {
251261
self.maxFrameSize = self.maxFrameSize.clamped(to: Self.allowedMaxFrameSizes)
252262
}
253263
}
264+
265+
/// The HTTP/2 max number of reset streams. Defaults to 32. Must be non-negative.
266+
public var maxResetStreams: Int = 32 {
267+
willSet {
268+
precondition(newValue >= 0, "maxResetStreams must be non-negative")
269+
}
270+
}
254271
}
255272
}
256273

@@ -299,6 +316,35 @@ extension GRPCChannelPool.Configuration {
299316
}
300317
}
301318

319+
#if canImport(Network)
320+
extension GRPCChannelPool.Configuration {
321+
public struct TransportServices: Sendable {
322+
/// Default transport services configuration.
323+
public static let defaults = Self()
324+
325+
@inlinable
326+
public static func with(_ configure: (inout Self) -> Void) -> Self {
327+
var configuration = Self.defaults
328+
configure(&configuration)
329+
return configuration
330+
}
331+
332+
/// A closure allowing to customise the `NWParameters` used when establishing a connection using `NIOTransportServices`.
333+
@available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *)
334+
public var nwParametersConfigurator: (@Sendable (NWParameters) -> Void)? {
335+
get {
336+
self._nwParametersConfigurator as! (@Sendable (NWParameters) -> Void)?
337+
}
338+
set {
339+
self._nwParametersConfigurator = newValue
340+
}
341+
}
342+
343+
private var _nwParametersConfigurator: (any Sendable)?
344+
}
345+
}
346+
#endif // canImport(Network)
347+
302348
/// The ID of a connection in the connection pool.
303349
public struct GRPCConnectionID: Hashable, Sendable, CustomStringConvertible {
304350
private enum Value: Sendable, Hashable {

0 commit comments

Comments
 (0)