Skip to content

Commit def2ced

Browse files
committed
Precompute interceptors when creating Server
1 parent 9cf1ae5 commit def2ced

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed

Sources/GRPCCore/Call/Server/RPCRouter.swift

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public struct RPCRouter: Sendable {
8282
}
8383

8484
@usableFromInline
85-
private(set) var handlers: [MethodDescriptor: RPCHandler]
85+
private(set) var handlers: [MethodDescriptor: (handler: RPCHandler, interceptors: [any ServerInterceptor])]
8686

8787
/// Creates a new router with no methods registered.
8888
public init() {
@@ -126,12 +126,25 @@ public struct RPCRouter: Sendable {
126126
_ context: ServerContext
127127
) async throws -> StreamingServerResponse<Output>
128128
) {
129-
self.handlers[descriptor] = RPCHandler(
129+
let handler = RPCHandler(
130130
method: descriptor,
131131
deserializer: deserializer,
132132
serializer: serializer,
133133
handler: handler
134134
)
135+
self.handlers[descriptor] = (handler, [])
136+
}
137+
138+
@inlinable
139+
public mutating func registerInterceptors(
140+
pipeline: [ServerInterceptorOperation]
141+
) {
142+
for descriptor in self.handlers.keys {
143+
let applicableOperations = pipeline.filter { $0.applies(to: descriptor) }
144+
if !applicableOperations.isEmpty {
145+
self.handlers[descriptor]?.interceptors = applicableOperations.map { $0.interceptor }
146+
}
147+
}
135148
}
136149

137150
/// Removes any handler registered for the specified method.
@@ -150,10 +163,9 @@ extension RPCRouter {
150163
RPCAsyncSequence<RPCRequestPart, any Error>,
151164
RPCWriter<RPCResponsePart>.Closable
152165
>,
153-
context: ServerContext,
154-
interceptors: [any ServerInterceptor]
166+
context: ServerContext
155167
) async {
156-
if let handler = self.handlers[stream.descriptor] {
168+
if let (handler, interceptors) = self.handlers[stream.descriptor] {
157169
await handler.handle(stream: stream, context: context, interceptors: interceptors)
158170
} else {
159171
// If this throws then the stream must be closed which we can't do anything about, so ignore

Sources/GRPCCore/GRPCServer.swift

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,6 @@ public final class GRPCServer: Sendable {
7878
/// The services registered which the server is serving.
7979
private let router: RPCRouter
8080

81-
/// A collection of ``ServerInterceptorOperation``s which may be applied to all accepted RPCs.
82-
///
83-
/// RPCs are intercepted in the order that interceptors are added. That is, a request received
84-
/// from the client will first be intercepted by the first added interceptor followed by the
85-
/// second, and so on.
86-
private let interceptors: [ServerInterceptorOperation]
87-
8881
/// The state of the server.
8982
private let state: Mutex<State>
9083

@@ -224,10 +217,12 @@ public final class GRPCServer: Sendable {
224217
router: RPCRouter,
225218
interceptorPipeline: [ServerInterceptorOperation]
226219
) {
220+
var router = router
221+
router.registerInterceptors(pipeline: interceptorPipeline)
222+
227223
self.state = Mutex(.notStarted)
228224
self.transport = transport
229225
self.router = router
230-
self.interceptors = interceptorPipeline
231226
}
232227

233228
/// Starts the server and runs until the registered transport has closed.
@@ -255,10 +250,7 @@ public final class GRPCServer: Sendable {
255250
try await transport.listen { stream, context in
256251
await self.router.handle(
257252
stream: stream,
258-
context: context,
259-
interceptors: self.interceptors
260-
.filter { $0.applies(to: context.descriptor) }
261-
.map { $0.interceptor }
253+
context: context
262254
)
263255
}
264256
} catch {

0 commit comments

Comments
 (0)