Browse Source

Propagate context to server RPC handlers (#2059)

Motivation:

The interceptors API has a context which, at the moment, only includes
the name of the RPC. This information is generally useful so should be
propagated to the server handler too. Information on the context can
also be extended later to include things like the identity of the remote
peer, or info about the state of the RPC.

Modifications:

- Rename 'ServerInterceptorContext' to 'ServerContext'
- Make the transport the source of the context and have that provide it
  to the 'listen' method. Propagate this through the server stack to the
  generated stubs.
- Update code generator to include the context
- Update generated code
- Update services

Results:

RPC handlers have a context provided by a transport
George Barnett 1 year ago
parent
commit
e359ec7b84
1 changed files with 43 additions and 12 deletions
  1. 43 12
      Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift

+ 43 - 12
Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift

@@ -241,7 +241,10 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         public protocol Helloworld_GreeterStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
         public protocol Helloworld_GreeterStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
           /// Sends a greeting.
           /// Sends a greeting.
-          func sayHello(request: GRPCCore.ServerRequest.Stream<Helloworld_HelloRequest>) async throws -> GRPCCore.ServerResponse.Stream<Helloworld_HelloReply>
+          func sayHello(
+            request: GRPCCore.ServerRequest.Stream<Helloworld_HelloRequest>,
+            context: GRPCCore.ServerContext
+          ) async throws -> GRPCCore.ServerResponse.Stream<Helloworld_HelloReply>
         }
         }
 
 
         /// Conformance to `GRPCCore.RegistrableRPCService`.
         /// Conformance to `GRPCCore.RegistrableRPCService`.
@@ -253,8 +256,11 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
               forMethod: Helloworld_Greeter.Method.SayHello.descriptor,
               forMethod: Helloworld_Greeter.Method.SayHello.descriptor,
               deserializer: GRPCProtobuf.ProtobufDeserializer<Helloworld_HelloRequest>(),
               deserializer: GRPCProtobuf.ProtobufDeserializer<Helloworld_HelloRequest>(),
               serializer: GRPCProtobuf.ProtobufSerializer<Helloworld_HelloReply>(),
               serializer: GRPCProtobuf.ProtobufSerializer<Helloworld_HelloReply>(),
-              handler: { request in
-                try await self.sayHello(request: request)
+              handler: { request, context in
+                try await self.sayHello(
+                  request: request,
+                  context: context
+                )
               }
               }
             )
             )
           }
           }
@@ -264,19 +270,29 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         public protocol Helloworld_GreeterServiceProtocol: Helloworld_Greeter.StreamingServiceProtocol {
         public protocol Helloworld_GreeterServiceProtocol: Helloworld_Greeter.StreamingServiceProtocol {
           /// Sends a greeting.
           /// Sends a greeting.
-          func sayHello(request: GRPCCore.ServerRequest.Single<Helloworld_HelloRequest>) async throws -> GRPCCore.ServerResponse.Single<Helloworld_HelloReply>
+          func sayHello(
+            request: GRPCCore.ServerRequest.Single<Helloworld_HelloRequest>,
+            context: GRPCCore.ServerContext
+          ) async throws -> GRPCCore.ServerResponse.Single<Helloworld_HelloReply>
         }
         }
 
 
         /// Partial conformance to `Helloworld_GreeterStreamingServiceProtocol`.
         /// Partial conformance to `Helloworld_GreeterStreamingServiceProtocol`.
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         extension Helloworld_Greeter.ServiceProtocol {
         extension Helloworld_Greeter.ServiceProtocol {
-          public func sayHello(request: GRPCCore.ServerRequest.Stream<Helloworld_HelloRequest>) async throws -> GRPCCore.ServerResponse.Stream<Helloworld_HelloReply> {
-            let response = try await self.sayHello(request: GRPCCore.ServerRequest.Single(stream: request))
+          public func sayHello(
+            request: GRPCCore.ServerRequest.Stream<Helloworld_HelloRequest>,
+            context: GRPCCore.ServerContext
+          ) async throws -> GRPCCore.ServerResponse.Stream<Helloworld_HelloReply> {
+            let response = try await self.sayHello(
+              request: GRPCCore.ServerRequest.Single(stream: request),
+              context: context
+            )
             return GRPCCore.ServerResponse.Stream(single: response)
             return GRPCCore.ServerResponse.Stream(single: response)
           }
           }
         }
         }
         """
         """
     )
     )
+
     try testCodeGeneration(
     try testCodeGeneration(
       proto: Google_Protobuf_FileDescriptorProto.helloWorldEmptyPackage,
       proto: Google_Protobuf_FileDescriptorProto.helloWorldEmptyPackage,
       indentation: 2,
       indentation: 2,
@@ -348,7 +364,10 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         package protocol GreeterStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
         package protocol GreeterStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
           /// Sends a greeting.
           /// Sends a greeting.
-          func sayHello(request: GRPCCore.ServerRequest.Stream<HelloRequest>) async throws -> GRPCCore.ServerResponse.Stream<HelloReply>
+          func sayHello(
+            request: GRPCCore.ServerRequest.Stream<HelloRequest>,
+            context: GRPCCore.ServerContext
+          ) async throws -> GRPCCore.ServerResponse.Stream<HelloReply>
         }
         }
 
 
         /// Conformance to `GRPCCore.RegistrableRPCService`.
         /// Conformance to `GRPCCore.RegistrableRPCService`.
@@ -360,8 +379,11 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
               forMethod: Greeter.Method.SayHello.descriptor,
               forMethod: Greeter.Method.SayHello.descriptor,
               deserializer: GRPCProtobuf.ProtobufDeserializer<HelloRequest>(),
               deserializer: GRPCProtobuf.ProtobufDeserializer<HelloRequest>(),
               serializer: GRPCProtobuf.ProtobufSerializer<HelloReply>(),
               serializer: GRPCProtobuf.ProtobufSerializer<HelloReply>(),
-              handler: { request in
-                try await self.sayHello(request: request)
+              handler: { request, context in
+                try await self.sayHello(
+                  request: request,
+                  context: context
+                )
               }
               }
             )
             )
           }
           }
@@ -371,14 +393,23 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         package protocol GreeterServiceProtocol: Greeter.StreamingServiceProtocol {
         package protocol GreeterServiceProtocol: Greeter.StreamingServiceProtocol {
           /// Sends a greeting.
           /// Sends a greeting.
-          func sayHello(request: GRPCCore.ServerRequest.Single<HelloRequest>) async throws -> GRPCCore.ServerResponse.Single<HelloReply>
+          func sayHello(
+            request: GRPCCore.ServerRequest.Single<HelloRequest>,
+            context: GRPCCore.ServerContext
+          ) async throws -> GRPCCore.ServerResponse.Single<HelloReply>
         }
         }
 
 
         /// Partial conformance to `GreeterStreamingServiceProtocol`.
         /// Partial conformance to `GreeterStreamingServiceProtocol`.
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
         extension Greeter.ServiceProtocol {
         extension Greeter.ServiceProtocol {
-          package func sayHello(request: GRPCCore.ServerRequest.Stream<HelloRequest>) async throws -> GRPCCore.ServerResponse.Stream<HelloReply> {
-            let response = try await self.sayHello(request: GRPCCore.ServerRequest.Single(stream: request))
+          package func sayHello(
+            request: GRPCCore.ServerRequest.Stream<HelloRequest>,
+            context: GRPCCore.ServerContext
+          ) async throws -> GRPCCore.ServerResponse.Stream<HelloReply> {
+            let response = try await self.sayHello(
+              request: GRPCCore.ServerRequest.Single(stream: request),
+              context: context
+            )
             return GRPCCore.ServerResponse.Stream(single: response)
             return GRPCCore.ServerResponse.Stream(single: response)
           }
           }
         }
         }