Skip to content

Commit 40cb657

Browse files
authored
Merge branch 'main' into v2/bag-o-bytes
2 parents d069bf1 + eb7ed6f commit 40cb657

23 files changed

+262
-252
lines changed

Sources/GRPCCore/Call/Client/ClientContext.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public struct ClientContext: Sendable {
4646
public var localPeer: String
4747

4848
/// Create a new client interceptor context.
49+
///
50+
/// - Parameters:
51+
/// - descriptor: A description of the method being called.
52+
/// - remotePeer: A description of the remote peer.
53+
/// - localPeer: A description of the local peer.
4954
public init(
5055
descriptor: MethodDescriptor,
5156
remotePeer: String,

Sources/GRPCCore/Call/Client/ClientInterceptor.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@
1414
* limitations under the License.
1515
*/
1616

17+
// - FIXME: Update example and documentation to show how to register an interceptor.
18+
1719
/// A type that intercepts requests and response for clients.
1820
///
1921
/// Interceptors allow you to inspect and modify requests and responses. Requests are intercepted
2022
/// before they are handed to a transport and responses are intercepted after they have been
2123
/// received from the transport. They are typically used for cross-cutting concerns like injecting
2224
/// metadata, validating messages, logging additional data, and tracing.
2325
///
24-
/// Interceptors are registered with the server via ``ClientInterceptorPipelineOperation``s.
26+
/// Interceptors are registered with the client via ``ConditionalInterceptor``s.
2527
/// You may register them for all services registered with a server, for RPCs directed to specific services, or
2628
/// for RPCs directed to specific methods. If you need to modify the behavior of an interceptor on a
2729
/// per-RPC basis in more detail, then you can use the ``ClientContext/descriptor`` to determine
2830
/// which RPC is being called and conditionalise behavior accordingly.
2931
///
30-
/// - TODO: Update example and documentation to show how to register an interceptor.
31-
///
3232
/// Some examples of simple interceptors follow.
3333
///
3434
/// ## Metadata injection
Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,16 @@
1414
* limitations under the License.
1515
*/
1616

17-
/// A `ClientInterceptorPipelineOperation` describes to which RPCs a client interceptor should be applied.
17+
/// Describes the conditions under which an interceptor should be applied.
1818
///
19-
/// You can configure a client interceptor to be applied to:
19+
/// You can configure interceptors to be applied to:
2020
/// - all RPCs and services;
2121
/// - requests directed only to specific services; or
2222
/// - requests directed only to specific methods (of a specific service).
2323
///
24-
/// - SeeAlso: ``ClientInterceptor`` for more information on client interceptors, and
25-
/// ``ServerInterceptorPipelineOperation`` for the server-side version of this type.
26-
public struct ClientInterceptorPipelineOperation: Sendable {
27-
/// The subject of a ``ClientInterceptorPipelineOperation``.
28-
/// The subject of an interceptor can either be all services and methods, only specific services, or only specific methods.
24+
/// - SeeAlso: ``ClientInterceptor`` and ``ServerInterceptor`` for more information on client and
25+
/// server interceptors, respectively.
26+
public struct ConditionalInterceptor<Interceptor: Sendable>: Sendable {
2927
public struct Subject: Sendable {
3028
internal enum Wrapped: Sendable {
3129
case all
@@ -41,21 +39,19 @@ public struct ClientInterceptorPipelineOperation: Sendable {
4139
/// An operation subject specifying an interceptor that will be applied only to RPCs directed to the specified services.
4240
/// - Parameters:
4341
/// - services: The list of service names for which this interceptor should intercept RPCs.
44-
/// - Returns: A ``ClientInterceptorPipelineOperation``.
4542
public static func services(_ services: Set<ServiceDescriptor>) -> Self {
4643
Self(wrapped: .services(services))
4744
}
4845

4946
/// An operation subject specifying an interceptor that will be applied only to RPCs directed to the specified service methods.
5047
/// - Parameters:
5148
/// - methods: The list of method descriptors for which this interceptor should intercept RPCs.
52-
/// - Returns: A ``ClientInterceptorPipelineOperation``.
5349
public static func methods(_ methods: Set<MethodDescriptor>) -> Self {
5450
Self(wrapped: .methods(methods))
5551
}
5652

5753
@usableFromInline
58-
internal func applies(to descriptor: MethodDescriptor) -> Bool {
54+
package func applies(to descriptor: MethodDescriptor) -> Bool {
5955
switch self.wrapped {
6056
case .all:
6157
return true
@@ -69,24 +65,15 @@ public struct ClientInterceptorPipelineOperation: Sendable {
6965
}
7066
}
7167

72-
/// The interceptor specified for this operation.
73-
public let interceptor: any ClientInterceptor
68+
/// The interceptor.
69+
public let interceptor: Interceptor
7470

7571
@usableFromInline
7672
internal let subject: Subject
7773

78-
private init(interceptor: any ClientInterceptor, appliesTo: Subject) {
74+
fileprivate init(interceptor: Interceptor, subject: Subject) {
7975
self.interceptor = interceptor
80-
self.subject = appliesTo
81-
}
82-
83-
/// Create an operation, specifying which ``ClientInterceptor`` to apply and to which ``Subject``.
84-
/// - Parameters:
85-
/// - interceptor: The ``ClientInterceptor`` to register with the client.
86-
/// - subject: The ``Subject`` to which the `interceptor` applies.
87-
/// - Returns: A ``ClientInterceptorPipelineOperation``.
88-
public static func apply(_ interceptor: any ClientInterceptor, to subject: Subject) -> Self {
89-
Self(interceptor: interceptor, appliesTo: subject)
76+
self.subject = subject
9077
}
9178

9279
/// Returns whether this ``ClientInterceptorPipelineOperation`` applies to the given `descriptor`.
@@ -97,3 +84,29 @@ public struct ClientInterceptorPipelineOperation: Sendable {
9784
self.subject.applies(to: descriptor)
9885
}
9986
}
87+
88+
extension ConditionalInterceptor where Interceptor == any ClientInterceptor {
89+
/// Create an operation, specifying which ``ClientInterceptor`` to apply and to which ``Subject``.
90+
/// - Parameters:
91+
/// - interceptor: The ``ClientInterceptor`` to register with the client.
92+
/// - subject: The ``Subject`` to which the `interceptor` applies.
93+
public static func apply(
94+
_ interceptor: any ClientInterceptor,
95+
to subject: Subject
96+
) -> Self {
97+
Self(interceptor: interceptor, subject: subject)
98+
}
99+
}
100+
101+
extension ConditionalInterceptor where Interceptor == any ServerInterceptor {
102+
/// Create an operation, specifying which ``ServerInterceptor`` to apply and to which ``Subject``.
103+
/// - Parameters:
104+
/// - interceptor: The ``ServerInterceptor`` to register with the server.
105+
/// - subject: The ``Subject`` to which the `interceptor` applies.
106+
public static func apply(
107+
_ interceptor: any ServerInterceptor,
108+
to subject: Subject
109+
) -> Self {
110+
Self(interceptor: interceptor, subject: subject)
111+
}
112+
}

Sources/GRPCCore/Call/Server/RPCRouter.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,10 @@ public struct RPCRouter<Transport: ServerTransport>: Sendable {
155155
/// only call this method _after_ you have registered all handlers.
156156
/// - Parameter pipeline: The interceptor pipeline operations to register to all currently-registered handlers. The order of the
157157
/// interceptors matters.
158-
/// - SeeAlso: ``ServerInterceptorPipelineOperation``.
159158
@inlinable
160-
public mutating func registerInterceptors(pipeline: [ServerInterceptorPipelineOperation]) {
159+
public mutating func registerInterceptors(
160+
pipeline: [ConditionalInterceptor<any ServerInterceptor>]
161+
) {
161162
for descriptor in self.handlers.keys {
162163
let applicableOperations = pipeline.filter { $0.applies(to: descriptor) }
163164
if !applicableOperations.isEmpty {

Sources/GRPCCore/Call/Server/ServerContext.swift

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,37 @@ public struct ServerContext: Sendable {
3030
/// - "ipv4:127.0.0.1:31415",
3131
/// - "ipv6:[::1]:443",
3232
/// - "in-process:27182".
33-
public var peer: String
33+
@available(*, deprecated, renamed: "remotePeer")
34+
public var peer: String {
35+
get { remotePeer }
36+
set { remotePeer = newValue }
37+
}
38+
39+
/// A description of the remote peer.
40+
///
41+
/// The format of the description should follow the pattern "<transport>:<address>" where
42+
/// "<transport>" indicates the underlying network transport (such as "ipv4", "unix", or
43+
/// "in-process"). This is a guideline for how descriptions should be formatted; different
44+
/// implementations may not follow this format so you shouldn't make assumptions based on it.
45+
///
46+
/// Some examples include:
47+
/// - "ipv4:127.0.0.1:31415",
48+
/// - "ipv6:[::1]:443",
49+
/// - "in-process:27182".
50+
public var remotePeer: String
51+
52+
/// A description of the local peer.
53+
///
54+
/// The format of the description should follow the pattern "<transport>:<address>" where
55+
/// "<transport>" indicates the underlying network transport (such as "ipv4", "unix", or
56+
/// "in-process"). This is a guideline for how descriptions should be formatted; different
57+
/// implementations may not follow this format so you shouldn't make assumptions based on it.
58+
///
59+
/// Some examples include:
60+
/// - "ipv4:127.0.0.1:31415",
61+
/// - "ipv6:[::1]:443",
62+
/// - "in-process:27182".
63+
public var localPeer: String
3464

3565
/// A handle for checking the cancellation status of an RPC.
3666
public var cancellation: RPCCancellationHandle
@@ -39,16 +69,19 @@ public struct ServerContext: Sendable {
3969
///
4070
/// - Parameters:
4171
/// - descriptor: A description of the method being called.
42-
/// - peer: A description of the remote peer.
72+
/// - remotePeer: A description of the remote peer.
73+
/// - localPeer: A description of the local peer.
4374
/// - cancellation: A cancellation handle. You can create a cancellation handle
4475
/// using ``withServerContextRPCCancellationHandle(_:)``.
4576
public init(
4677
descriptor: MethodDescriptor,
47-
peer: String,
78+
remotePeer: String,
79+
localPeer: String,
4880
cancellation: RPCCancellationHandle
4981
) {
5082
self.descriptor = descriptor
51-
self.peer = peer
83+
self.remotePeer = remotePeer
84+
self.localPeer = localPeer
5285
self.cancellation = cancellation
5386
}
5487
}

Sources/GRPCCore/Call/Server/ServerInterceptor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
/// been returned from a service. They are typically used for cross-cutting concerns like filtering
2222
/// requests, validating messages, logging additional data, and tracing.
2323
///
24-
/// Interceptors can be registered with the server either directly or via ``ServerInterceptorPipelineOperation``s.
24+
/// Interceptors can be registered with the server either directly or via ``ConditionalInterceptor``s.
2525
/// You may register them for all services registered with a server, for RPCs directed to specific services, or
2626
/// for RPCs directed to specific methods. If you need to modify the behavior of an interceptor on a
2727
/// per-RPC basis in more detail, then you can use the ``ServerContext/descriptor`` to determine

Sources/GRPCCore/Call/Server/ServerInterceptorPipelineOperation.swift

Lines changed: 0 additions & 99 deletions
This file was deleted.

Sources/GRPCCore/Configuration/MethodConfig.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
///
1919
/// See also: https://github.com/grpc/grpc-proto/blob/0b30c8c05277ab78ec72e77c9cbf66a26684673d/grpc/service_config/service_config.proto
2020
public struct MethodConfig: Hashable, Sendable {
21+
/// The name of a method to which the method config applies.
2122
public struct Name: Sendable, Hashable {
2223
/// The name of the service, including the namespace.
2324
///
@@ -143,6 +144,7 @@ public struct MethodConfig: Hashable, Sendable {
143144
}
144145
}
145146

147+
/// Whether an RPC should be retried or hedged.
146148
public struct RPCExecutionPolicy: Hashable, Sendable {
147149
@usableFromInline
148150
enum Wrapped: Hashable, Sendable {

Sources/GRPCCore/Configuration/ServiceConfig.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616

1717
/// Service configuration values.
1818
///
19-
/// See also: https://github.com/grpc/grpc-proto/blob/0b30c8c05277ab78ec72e77c9cbf66a26684673d/grpc/service_config/service_config.proto
19+
/// A service config mostly contains parameters describing how clients connecting to a service
20+
/// should behave (for example, the load balancing policy to use).
21+
///
22+
/// The schema is described by [`grpc/service_config/service_config.proto`](https://github.com/grpc/grpc-proto/blob/0b30c8c05277ab78ec72e77c9cbf66a26684673d/grpc/service_config/service_config.proto)
23+
/// in the `grpc/grpc-proto` GitHub repository although gRPC uses it in its JSON form rather than
24+
/// the Protobuf form.
2025
public struct ServiceConfig: Hashable, Sendable {
2126
/// Per-method configuration.
2227
public var methodConfig: [MethodConfig]
File renamed without changes.

0 commit comments

Comments
 (0)