Sfoglia il codice sorgente

Propagate generics from AsyncSequence to RPCAsyncSequence (#1980)

Motivation:

`RPCAsyncSequence` was added before we raised the minimum 
swift version to 6.0. As a result it used a fully erased sequence where
the iterator had to upcast from `Any` to the expected type. This 
causes an allocation per message.

Modification:

- Make `RPCAsyncSequence` generic over its `Element` and its `Failure` type
- This required bumping its availability to the latest SDKs which is 
  rather viral.
- Modify the code generator to allow visionOS to be specified
- Modify the code gen translator to bump the availability of generated code
- Regenerate

Result:

Fewer allocations
George Barnett 1 anno fa
parent
commit
6098f642a2
20 ha cambiato i file con 58 aggiunte e 58 eliminazioni
  1. 10 10
      Sources/GRPCHTTP2Core/Client/Connection/GRPCChannel.swift
  2. 1 1
      Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+IPv4.swift
  3. 1 1
      Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+IPv6.swift
  4. 1 1
      Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+UDS.swift
  5. 1 1
      Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+VSOCK.swift
  6. 5 5
      Sources/GRPCHTTP2Core/Client/Resolver/NameResolver.swift
  7. 1 1
      Sources/GRPCHTTP2Core/Client/Resolver/NameResolverRegistry.swift
  8. 3 3
      Sources/GRPCHTTP2Core/Internal/ConstantAsyncSequence.swift
  9. 1 1
      Sources/GRPCHTTP2Core/Internal/NIOChannelPipeline+GRPC.swift
  10. 4 4
      Sources/GRPCHTTP2TransportNIOPosix/HTTP2ClientTransport+Posix.swift
  11. 2 2
      Sources/GRPCHTTP2TransportNIOPosix/HTTP2ServerTransport+Posix.swift
  12. 2 2
      Sources/GRPCHTTP2TransportNIOTransportServices/HTTP2ServerTransport+TransportServices.swift
  13. 3 3
      Tests/GRPCHTTP2CoreTests/Client/Connection/GRPCChannelTests.swift
  14. 3 3
      Tests/GRPCHTTP2CoreTests/Client/Connection/Utilities/NameResolvers.swift
  15. 2 2
      Tests/GRPCHTTP2CoreTests/Client/Resolver/NameResolverRegistryTests.swift
  16. 2 2
      Tests/GRPCHTTP2TransportTests/ControlService.swift
  17. 12 12
      Tests/GRPCHTTP2TransportTests/Generated/control.grpc.swift
  18. 1 1
      Tests/GRPCHTTP2TransportTests/HTTP2TransportNIOPosixTests.swift
  19. 1 1
      Tests/GRPCHTTP2TransportTests/HTTP2TransportNIOTransportServicesTests.swift
  20. 2 2
      Tests/GRPCHTTP2TransportTests/HTTP2TransportTests.swift

+ 10 - 10
Sources/GRPCHTTP2Core/Client/Connection/GRPCChannel.swift

@@ -18,7 +18,7 @@ import Atomics
 import DequeModule
 import GRPCCore
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 package struct GRPCChannel: ClientTransport {
   private enum Input: Sendable {
     /// Close the channel, if possible.
@@ -124,7 +124,7 @@ package struct GRPCChannel: ClientTransport {
     self._connectivityState.continuation.yield(.idle)
 
     await withDiscardingTaskGroup { group in
-      var iterator: Optional<RPCAsyncSequence<NameResolutionResult>.AsyncIterator>
+      var iterator: Optional<RPCAsyncSequence<NameResolutionResult, any Error>.AsyncIterator>
 
       // The resolver can either push or pull values. If it pushes values the channel should
       // listen for new results. Otherwise the channel will pull values as and when necessary.
@@ -203,7 +203,7 @@ package struct GRPCChannel: ClientTransport {
         return try await stream.execute { inbound, outbound in
           let rpcStream = RPCStream(
             descriptor: stream.descriptor,
-            inbound: RPCAsyncSequence(wrapping: inbound),
+            inbound: RPCAsyncSequence<RPCResponsePart, any Error>(wrapping: inbound),
             outbound: RPCWriter.Closable(wrapping: outbound)
           )
           return try await closure(rpcStream)
@@ -225,7 +225,7 @@ package struct GRPCChannel: ClientTransport {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel {
   package struct Config: Sendable {
     /// Configuration for HTTP/2 connections.
@@ -254,7 +254,7 @@ extension GRPCChannel {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel {
   enum MakeStreamResult {
     /// A stream was created, use it.
@@ -347,7 +347,7 @@ extension GRPCChannel {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel {
   private func handleClose(in group: inout DiscardingTaskGroup) {
     switch self.state.withLockedValue({ $0.close() }) {
@@ -523,7 +523,7 @@ extension GRPCChannel {
     _ event: LoadBalancerEvent,
     loadBalancerID: LoadBalancerID,
     in group: inout DiscardingTaskGroup,
-    iterator: inout RPCAsyncSequence<NameResolutionResult>.AsyncIterator?
+    iterator: inout RPCAsyncSequence<NameResolutionResult, any Error>.AsyncIterator?
   ) async {
     switch event {
     case .connectivityStateChanged(let connectivityState):
@@ -557,7 +557,7 @@ extension GRPCChannel {
   }
 
   private func resolve(
-    iterator: inout RPCAsyncSequence<NameResolutionResult>.AsyncIterator?,
+    iterator: inout RPCAsyncSequence<NameResolutionResult, any Error>.AsyncIterator?,
     in group: inout DiscardingTaskGroup
   ) async {
     guard var iterator = iterator else { return }
@@ -574,7 +574,7 @@ extension GRPCChannel {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel {
   struct StateMachine {
     enum State {
@@ -649,7 +649,7 @@ extension GRPCChannel {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel.StateMachine {
   mutating func start() {
     precondition(!self.running, "channel must only be started once")

+ 1 - 1
Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+IPv4.swift

@@ -54,7 +54,7 @@ extension ResolvableTarget where Self == ResolvableTargets.IPv4 {
   }
 }
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension NameResolvers {
   /// A ``NameResolverFactory`` for ``ResolvableTargets/IPv4`` targets.
   ///

+ 1 - 1
Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+IPv6.swift

@@ -54,7 +54,7 @@ extension ResolvableTarget where Self == ResolvableTargets.IPv6 {
   }
 }
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension NameResolvers {
   /// A ``NameResolverFactory`` for ``ResolvableTargets/IPv6`` targets.
   ///

+ 1 - 1
Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+UDS.swift

@@ -40,7 +40,7 @@ extension ResolvableTarget where Self == ResolvableTargets.UnixDomainSocket {
   }
 }
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension NameResolvers {
   /// A ``NameResolverFactory`` for ``ResolvableTargets/UnixDomainSocket`` targets.
   ///

+ 1 - 1
Sources/GRPCHTTP2Core/Client/Resolver/NameResolver+VSOCK.swift

@@ -44,7 +44,7 @@ extension ResolvableTarget where Self == ResolvableTargets.VirtualSocket {
   }
 }
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension NameResolvers {
   /// A ``NameResolverFactory`` for ``ResolvableTargets/VirtualSocket`` targets.
   ///

+ 5 - 5
Sources/GRPCHTTP2Core/Client/Resolver/NameResolver.swift

@@ -17,7 +17,7 @@
 import GRPCCore
 
 /// A name resolver can provide resolved addresses and service configuration values over time.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 public struct NameResolver: Sendable {
   /// A sequence of name resolution results.
   ///
@@ -27,7 +27,7 @@ public struct NameResolver: Sendable {
   ///
   /// Resolvers with the ``UpdateMode-swift.enum/pull`` update mode shouldn't be subscribed to,
   /// instead you should create an iterator and ask for new results as and when necessary.
-  public var names: RPCAsyncSequence<NameResolutionResult>
+  public var names: RPCAsyncSequence<NameResolutionResult, any Error>
 
   /// How ``names`` is updated and should be consumed.
   public let updateMode: UpdateMode
@@ -52,7 +52,7 @@ public struct NameResolver: Sendable {
   }
 
   /// Create a new name resolver.
-  public init(names: RPCAsyncSequence<NameResolutionResult>, updateMode: UpdateMode) {
+  public init(names: RPCAsyncSequence<NameResolutionResult, any Error>, updateMode: UpdateMode) {
     self.names = names
     self.updateMode = updateMode
   }
@@ -94,7 +94,7 @@ public struct Endpoint: Hashable, Sendable {
 }
 
 /// A resolver capable of resolving targets of type ``Target``.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 public protocol NameResolverFactory<Target> {
   /// The type of ``ResolvableTarget`` this factory makes resolvers for.
   associatedtype Target: ResolvableTarget
@@ -106,7 +106,7 @@ public protocol NameResolverFactory<Target> {
   func resolver(for target: Target) -> NameResolver
 }
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension NameResolverFactory {
   /// Returns whether the given target is compatible with this factory.
   ///

+ 1 - 1
Sources/GRPCHTTP2Core/Client/Resolver/NameResolverRegistry.swift

@@ -37,7 +37,7 @@
 ///   // ...
 /// }
 /// ```
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 public struct NameResolverRegistry {
   private enum Factory {
     case ipv4(NameResolvers.IPv4)

+ 3 - 3
Sources/GRPCHTTP2Core/Internal/ConstantAsyncSequence.swift

@@ -41,9 +41,9 @@ private struct ConstantAsyncSequence<Element: Sendable>: AsyncSequence, Sendable
   }
 }
 
-@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
-extension RPCAsyncSequence where Element: Sendable {
-  static func constant(_ element: Element) -> RPCAsyncSequence<Element> {
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
+extension RPCAsyncSequence where Element: Sendable, Failure == any Error {
+  static func constant(_ element: Element) -> RPCAsyncSequence<Element, any Error> {
     return RPCAsyncSequence(wrapping: ConstantAsyncSequence(element: element))
   }
 }

+ 1 - 1
Sources/GRPCHTTP2Core/Internal/NIOChannelPipeline+GRPC.swift

@@ -103,7 +103,7 @@ extension ChannelPipeline.SynchronousOperations {
 }
 
 extension ChannelPipeline.SynchronousOperations {
-  @available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+  @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
   package func configureGRPCClientPipeline(
     channel: any Channel,
     config: GRPCChannel.Config

+ 4 - 4
Sources/GRPCHTTP2TransportNIOPosix/HTTP2ClientTransport+Posix.swift

@@ -19,7 +19,7 @@ import GRPCHTTP2Core
 import NIOCore
 import NIOPosix
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension HTTP2ClientTransport {
   /// A `ClientTransport` using HTTP/2 built on top of `NIOPosix`.
   ///
@@ -119,7 +119,7 @@ extension HTTP2ClientTransport {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension HTTP2ClientTransport.Posix {
   struct Connector: HTTP2Connector {
     private let config: HTTP2ClientTransport.Posix.Config
@@ -149,7 +149,7 @@ extension HTTP2ClientTransport.Posix {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension HTTP2ClientTransport.Posix {
   public struct Config: Sendable {
     /// Configuration for HTTP/2 connections.
@@ -191,7 +191,7 @@ extension HTTP2ClientTransport.Posix {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel.Config {
   init(posix: HTTP2ClientTransport.Posix.Config) {
     self.init(

+ 2 - 2
Sources/GRPCHTTP2TransportNIOPosix/HTTP2ServerTransport+Posix.swift

@@ -23,7 +23,7 @@ import NIOPosix
 
 extension HTTP2ServerTransport {
   /// A NIOPosix-backed implementation of a server transport.
-  @available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+  @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
   public struct Posix: ServerTransport {
     private let address: GRPCHTTP2Core.SocketAddress
     private let config: Config
@@ -292,7 +292,7 @@ extension HTTP2ServerTransport {
 
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension HTTP2ServerTransport.Posix {
   /// Configuration for the ``GRPCHTTP2TransportNIOPosix/GRPCHTTP2Core/HTTP2ServerTransport/Posix``.
   public struct Config: Sendable {

+ 2 - 2
Sources/GRPCHTTP2TransportNIOTransportServices/HTTP2ServerTransport+TransportServices.swift

@@ -24,7 +24,7 @@ import NIOTransportServices
 
 extension HTTP2ServerTransport {
   /// A NIO Transport Services-backed implementation of a server transport.
-  @available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+  @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
   public struct TransportServices: ServerTransport {
     private let address: GRPCHTTP2Core.SocketAddress
     private let config: Config
@@ -283,7 +283,7 @@ extension HTTP2ServerTransport {
 
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension HTTP2ServerTransport.TransportServices {
   /// Configuration for the ``GRPCHTTP2TransportNIOTransportServices/GRPCHTTP2Core/HTTP2ServerTransport/TransportServices``.
   public struct Config: Sendable {

+ 3 - 3
Tests/GRPCHTTP2CoreTests/Client/Connection/GRPCChannelTests.swift

@@ -20,7 +20,7 @@ import NIOHTTP2
 import NIOPosix
 import XCTest
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 final class GRPCChannelTests: XCTestCase {
   func testDefaultServiceConfig() throws {
     var serviceConfig = ServiceConfig()
@@ -798,7 +798,7 @@ final class GRPCChannelTests: XCTestCase {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel.Config {
   static var defaults: Self {
     Self(
@@ -816,7 +816,7 @@ extension Endpoint {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension GRPCChannel {
   fileprivate func serverAddress() async throws -> String? {
     let values: Metadata.StringValues? = try await self.withStream(

+ 3 - 3
Tests/GRPCHTTP2CoreTests/Client/Connection/Utilities/NameResolvers.swift

@@ -17,7 +17,7 @@
 import GRPCCore
 import GRPCHTTP2Core
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension NameResolver {
   static func `static`(
     endpoints: [Endpoint],
@@ -36,8 +36,8 @@ extension NameResolver {
 
   static func `dynamic`(
     updateMode: UpdateMode
-  ) -> (Self, AsyncStream<NameResolutionResult>.Continuation) {
-    let (stream, continuation) = AsyncStream.makeStream(of: NameResolutionResult.self)
+  ) -> (Self, AsyncThrowingStream<NameResolutionResult, any Error>.Continuation) {
+    let (stream, continuation) = AsyncThrowingStream.makeStream(of: NameResolutionResult.self)
     let resolver = NameResolver(names: RPCAsyncSequence(wrapping: stream), updateMode: updateMode)
     return (resolver, continuation)
   }

+ 2 - 2
Tests/GRPCHTTP2CoreTests/Client/Resolver/NameResolverRegistryTests.swift

@@ -18,7 +18,7 @@ import GRPCCore
 import GRPCHTTP2Core
 import XCTest
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 final class NameResolverRegistryTests: XCTestCase {
   struct FailingResolver: NameResolverFactory {
     typealias Target = StringTarget
@@ -152,7 +152,7 @@ final class NameResolverRegistryTests: XCTestCase {
     struct CustomResolver: NameResolverFactory {
       func resolver(for target: EmptyTarget) -> NameResolver {
         return NameResolver(
-          names: RPCAsyncSequence(wrapping: AsyncStream { $0.finish() }),
+          names: RPCAsyncSequence(wrapping: AsyncThrowingStream { $0.finish() }),
           updateMode: .push
         )
       }

+ 2 - 2
Tests/GRPCHTTP2TransportTests/ControlService.swift

@@ -18,7 +18,7 @@ import GRPCCore
 
 import struct Foundation.Data
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 struct ControlService: ControlStreamingServiceProtocol {
   func unary(
     request: ServerRequest.Stream<Control.Method.Unary.Input>
@@ -45,7 +45,7 @@ struct ControlService: ControlStreamingServiceProtocol {
   }
 }
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension ControlService {
   private func handle(
     request: ServerRequest.Stream<ControlInput>

+ 12 - 12
Tests/GRPCHTTP2TransportTests/Generated/control.grpc.swift

@@ -66,13 +66,13 @@ internal enum Control {
             BidiStream.descriptor
         ]
     }
-    @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+    @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
     internal typealias StreamingServiceProtocol = ControlStreamingServiceProtocol
-    @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+    @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
     internal typealias ServiceProtocol = ControlServiceProtocol
-    @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+    @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
     internal typealias ClientProtocol = ControlClientProtocol
-    @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+    @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
     internal typealias Client = ControlClient
 }
 
@@ -80,7 +80,7 @@ internal enum Control {
 ///
 /// The control service has one RPC of each kind, the input to each RPC controls
 /// the output.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 internal protocol ControlStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
     func unary(request: ServerRequest.Stream<ControlInput>) async throws -> ServerResponse.Stream<ControlOutput>
 
@@ -92,9 +92,9 @@ internal protocol ControlStreamingServiceProtocol: GRPCCore.RegistrableRPCServic
 }
 
 /// Conformance to `GRPCCore.RegistrableRPCService`.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension Control.StreamingServiceProtocol {
-    @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+    @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
     internal func registerMethods(with router: inout GRPCCore.RPCRouter) {
         router.registerHandler(
             forMethod: Control.Method.Unary.descriptor,
@@ -135,7 +135,7 @@ extension Control.StreamingServiceProtocol {
 ///
 /// The control service has one RPC of each kind, the input to each RPC controls
 /// the output.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 internal protocol ControlServiceProtocol: Control.StreamingServiceProtocol {
     func unary(request: ServerRequest.Single<ControlInput>) async throws -> ServerResponse.Single<ControlOutput>
 
@@ -147,7 +147,7 @@ internal protocol ControlServiceProtocol: Control.StreamingServiceProtocol {
 }
 
 /// Partial conformance to `ControlStreamingServiceProtocol`.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension Control.ServiceProtocol {
     internal func unary(request: ServerRequest.Stream<ControlInput>) async throws -> ServerResponse.Stream<ControlOutput> {
         let response = try await self.unary(request: ServerRequest.Single(stream: request))
@@ -169,7 +169,7 @@ extension Control.ServiceProtocol {
 ///
 /// The control service has one RPC of each kind, the input to each RPC controls
 /// the output.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 internal protocol ControlClientProtocol: Sendable {
     func unary<R>(
         request: ClientRequest.Single<ControlInput>,
@@ -204,7 +204,7 @@ internal protocol ControlClientProtocol: Sendable {
     ) async throws -> R where R: Sendable
 }
 
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension Control.ClientProtocol {
     internal func unary<R>(
         request: ClientRequest.Single<ControlInput>,
@@ -267,7 +267,7 @@ extension Control.ClientProtocol {
 ///
 /// The control service has one RPC of each kind, the input to each RPC controls
 /// the output.
-@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 internal struct ControlClient: Control.ClientProtocol {
     private let client: GRPCCore.GRPCClient
 

+ 1 - 1
Tests/GRPCHTTP2TransportTests/HTTP2TransportNIOPosixTests.swift

@@ -19,7 +19,7 @@ import GRPCHTTP2Core
 import GRPCHTTP2TransportNIOPosix
 import XCTest
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 final class HTTP2TransportNIOPosixTests: XCTestCase {
   func testGetListeningAddress_IPv4() async throws {
     let transport = GRPCHTTP2Core.HTTP2ServerTransport.Posix(

+ 1 - 1
Tests/GRPCHTTP2TransportTests/HTTP2TransportNIOTransportServicesTests.swift

@@ -20,7 +20,7 @@ import GRPCHTTP2Core
 import GRPCHTTP2TransportNIOTransportServices
 import XCTest
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 final class HTTP2TransportNIOTransportServicesTests: XCTestCase {
   func testGetListeningAddress_IPv4() async throws {
     let transport = GRPCHTTP2Core.HTTP2ServerTransport.TransportServices(

+ 2 - 2
Tests/GRPCHTTP2TransportTests/HTTP2TransportTests.swift

@@ -21,7 +21,7 @@ import GRPCHTTP2TransportNIOTransportServices
 import GRPCProtobuf
 import XCTest
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 final class HTTP2TransportTests: XCTestCase {
   // A combination of client and server transport kinds.
   struct Transport: Sendable, CustomStringConvertible {
@@ -1411,7 +1411,7 @@ final class HTTP2TransportTests: XCTestCase {
   }
 }
 
-@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
 extension [HTTP2TransportTests.Transport] {
   static let supported = [
     HTTP2TransportTests.Transport(server: .posix, client: .posix),