Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Sources/GRPCCore/Documentation.docc/Development/Design.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ can either be applied to all RPCs or to specific services.
The call layer includes a concrete ``GRPCClient`` which provides API to execute all
four types of RPC against a ``ClientTransport``. These methods are:

- ``GRPCClient/unary(request:descriptor:serializer:deserializer:options:handler:)``,
- ``GRPCClient/clientStreaming(request:descriptor:serializer:deserializer:options:handler:)``,
- ``GRPCClient/serverStreaming(request:descriptor:serializer:deserializer:options:handler:)``, and
- ``GRPCClient/bidirectionalStreaming(request:descriptor:serializer:deserializer:options:handler:)``.
- ``GRPCClient/unary(request:descriptor:serializer:deserializer:options:onResponse:)``,
- ``GRPCClient/clientStreaming(request:descriptor:serializer:deserializer:options:onResponse:)``,
- ``GRPCClient/serverStreaming(request:descriptor:serializer:deserializer:options:onResponse:)``, and
- ``GRPCClient/bidirectionalStreaming(request:descriptor:serializer:deserializer:options:onResponse:)``.

As lower level methods they require you to pass in a serializer and
deserializer, as well as the descriptor of the method being called. Each method
Expand Down
48 changes: 28 additions & 20 deletions Sources/GRPCCore/GRPCClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ private import Synchronization
/// A ``GRPCClient`` communicates to a server via a ``ClientTransport``.
///
/// You can start RPCs to the server by calling the corresponding method:
/// - ``unary(request:descriptor:serializer:deserializer:options:handler:)``
/// - ``clientStreaming(request:descriptor:serializer:deserializer:options:handler:)``
/// - ``serverStreaming(request:descriptor:serializer:deserializer:options:handler:)``
/// - ``bidirectionalStreaming(request:descriptor:serializer:deserializer:options:handler:)``
/// - ``unary(request:descriptor:serializer:deserializer:options:onResponse:)``
/// - ``clientStreaming(request:descriptor:serializer:deserializer:options:onResponse:)``
/// - ``serverStreaming(request:descriptor:serializer:deserializer:options:onResponse:)``
/// - ``bidirectionalStreaming(request:descriptor:serializer:deserializer:options:onResponse:)``
///
/// However, in most cases you should prefer wrapping the ``GRPCClient`` with a generated stub.
///
Expand Down Expand Up @@ -247,16 +247,18 @@ public final class GRPCClient: Sendable {
/// - serializer: A request serializer.
/// - deserializer: A response deserializer.
/// - options: Call specific options.
/// - handler: A unary response handler.
/// - handleResponse: A unary response handler.
///
/// - Returns: The return value from the `handler`.
/// - Returns: The return value from the `handleResponse`.
public func unary<Request, Response, ReturnValue: Sendable>(
request: ClientRequest<Request>,
descriptor: MethodDescriptor,
serializer: some MessageSerializer<Request>,
deserializer: some MessageDeserializer<Response>,
options: CallOptions,
handler: @Sendable @escaping (ClientResponse<Response>) async throws -> ReturnValue
onResponse handleResponse: @Sendable @escaping (
_ response: ClientResponse<Response>
) async throws -> ReturnValue
) async throws -> ReturnValue {
try await self.bidirectionalStreaming(
request: StreamingClientRequest(single: request),
Expand All @@ -266,7 +268,7 @@ public final class GRPCClient: Sendable {
options: options
) { stream in
let singleResponse = await ClientResponse(stream: stream)
return try await handler(singleResponse)
return try await handleResponse(singleResponse)
}
}

Expand All @@ -278,16 +280,18 @@ public final class GRPCClient: Sendable {
/// - serializer: A request serializer.
/// - deserializer: A response deserializer.
/// - options: Call specific options.
/// - handler: A unary response handler.
/// - handleResponse: A unary response handler.
///
/// - Returns: The return value from the `handler`.
/// - Returns: The return value from the `handleResponse`.
public func clientStreaming<Request, Response, ReturnValue: Sendable>(
request: StreamingClientRequest<Request>,
descriptor: MethodDescriptor,
serializer: some MessageSerializer<Request>,
deserializer: some MessageDeserializer<Response>,
options: CallOptions,
handler: @Sendable @escaping (ClientResponse<Response>) async throws -> ReturnValue
onResponse handleResponse: @Sendable @escaping (
_ response: ClientResponse<Response>
) async throws -> ReturnValue
) async throws -> ReturnValue {
try await self.bidirectionalStreaming(
request: request,
Expand All @@ -297,7 +301,7 @@ public final class GRPCClient: Sendable {
options: options
) { stream in
let singleResponse = await ClientResponse(stream: stream)
return try await handler(singleResponse)
return try await handleResponse(singleResponse)
}
}

Expand All @@ -309,24 +313,26 @@ public final class GRPCClient: Sendable {
/// - serializer: A request serializer.
/// - deserializer: A response deserializer.
/// - options: Call specific options.
/// - handler: A response stream handler.
/// - handleResponse: A response stream handler.
///
/// - Returns: The return value from the `handler`.
/// - Returns: The return value from the `handleResponse`.
public func serverStreaming<Request, Response, ReturnValue: Sendable>(
request: ClientRequest<Request>,
descriptor: MethodDescriptor,
serializer: some MessageSerializer<Request>,
deserializer: some MessageDeserializer<Response>,
options: CallOptions,
handler: @Sendable @escaping (StreamingClientResponse<Response>) async throws -> ReturnValue
onResponse handleResponse: @Sendable @escaping (
_ response: StreamingClientResponse<Response>
) async throws -> ReturnValue
) async throws -> ReturnValue {
try await self.bidirectionalStreaming(
request: StreamingClientRequest(single: request),
descriptor: descriptor,
serializer: serializer,
deserializer: deserializer,
options: options,
handler: handler
onResponse: handleResponse
)
}

Expand All @@ -341,16 +347,18 @@ public final class GRPCClient: Sendable {
/// - serializer: A request serializer.
/// - deserializer: A response deserializer.
/// - options: Call specific options.
/// - handler: A response stream handler.
/// - handleResponse: A response stream handler.
///
/// - Returns: The return value from the `handler`.
/// - Returns: The return value from the `handleResponse`.
public func bidirectionalStreaming<Request, Response, ReturnValue: Sendable>(
request: StreamingClientRequest<Request>,
descriptor: MethodDescriptor,
serializer: some MessageSerializer<Request>,
deserializer: some MessageDeserializer<Response>,
options: CallOptions,
handler: @Sendable @escaping (StreamingClientResponse<Response>) async throws -> ReturnValue
onResponse handleResponse: @Sendable @escaping (
_ response: StreamingClientResponse<Response>
) async throws -> ReturnValue
) async throws -> ReturnValue {
let applicableInterceptors = try self.stateMachine.withLock {
try $0.checkExecutableAndGetApplicableInterceptors(for: descriptor)
Expand All @@ -367,7 +375,7 @@ public final class GRPCClient: Sendable {
deserializer: deserializer,
transport: self.transport,
interceptors: applicableInterceptors,
handler: handler
handler: handleResponse
)
}
}
Expand Down
Loading