Skip to content

Commit

Permalink
Add a convenience method for creating in-process client/server (#1738)
Browse files Browse the repository at this point in the history
Motivation:

To use the in-process transport users must create a server and then a
client depending on that server. It rarely makes sense to create one
without the other and I have written more or less the same extension in
three places to do this for me and return a pair. This should just be
made into API.

Modifications:

- Add a `InProcessTransport.makePair()` convenience method
- Replace use of old helpers

Result:

It's easier to create in-process transport.
  • Loading branch information
glbrntt authored Dec 8, 2023
1 parent 7986535 commit 471fe8b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 24 deletions.
43 changes: 43 additions & 0 deletions Sources/GRPCInProcessTransport/InProcessTransport.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2023, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import GRPCCore

public enum InProcessTransport {
/// Returns a pair containing an ``InProcessServerTransport`` and an ``InProcessClientTransport``.
///
/// This function is purely for convenience and does no more than constructing a server transport
/// and a client using that server transport.
///
/// - Parameters:
/// - methodConfiguration: Method specific configuration used by the client transport to
/// determine how RPCs should be executed.
/// - retryThrottle: The retry throttle the client transport uses to determine whether a call
/// should be retried.
/// - Returns: A tuple containing the connected server and client in-process transports.
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
public static func makePair(
methodConfiguration: MethodConfigurations = MethodConfigurations(),
retryThrottle: RetryThrottle? = nil
) -> (server: InProcessServerTransport, client: InProcessClientTransport) {
let server = InProcessServerTransport()
let client = InProcessClientTransport(
server: server,
methodConfiguration: methodConfiguration,
retryThrottle: retryThrottle
)
return (server, client)
}
}
18 changes: 4 additions & 14 deletions Tests/GRPCCoreTests/GRPCClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,12 @@ import XCTest

@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
final class GRPCClientTests: XCTestCase {
func makeInProcessPair() -> (client: InProcessClientTransport, server: InProcessServerTransport) {
let server = InProcessServerTransport()
let client = InProcessClientTransport(
server: server,
methodConfiguration: MethodConfigurations()
)

return (client, server)
}

func withInProcessConnectedClient(
services: [any RegistrableRPCService],
interceptors: [any ClientInterceptor] = [],
_ body: (GRPCClient, GRPCServer) async throws -> Void
) async throws {
let inProcess = self.makeInProcessPair()
let inProcess = InProcessTransport.makePair()
let client = GRPCClient(transport: inProcess.client, interceptors: interceptors)
let server = GRPCServer(transports: [inProcess.server], services: services)

Expand Down Expand Up @@ -325,7 +315,7 @@ final class GRPCClientTests: XCTestCase {
}

func testCancelRunningClient() async throws {
let inProcess = self.makeInProcessPair()
let inProcess = InProcessTransport.makePair()
let client = GRPCClient(transport: inProcess.client)

try await withThrowingTaskGroup(of: Void.self) { group in
Expand Down Expand Up @@ -374,7 +364,7 @@ final class GRPCClientTests: XCTestCase {
}

func testRunStoppedClient() async throws {
let (clientTransport, _) = self.makeInProcessPair()
let (_, clientTransport) = InProcessTransport.makePair()
let client = GRPCClient(transport: clientTransport)
// Run the client.
let task = Task { try await client.run() }
Expand All @@ -390,7 +380,7 @@ final class GRPCClientTests: XCTestCase {
}

func testRunAlreadyRunningClient() async throws {
let (clientTransport, _) = self.makeInProcessPair()
let (_, clientTransport) = InProcessTransport.makePair()
let client = GRPCClient(transport: clientTransport)
// Run the client.
let task = Task { try await client.run() }
Expand Down
14 changes: 4 additions & 10 deletions Tests/GRPCCoreTests/GRPCServerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,12 @@ import XCTest

@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
final class GRPCServerTests: XCTestCase {
func makeInProcessPair() -> (client: InProcessClientTransport, server: InProcessServerTransport) {
let server = InProcessServerTransport()
let client = InProcessClientTransport(server: server)

return (client, server)
}

func withInProcessClientConnectedToServer(
services: [any RegistrableRPCService],
interceptors: [any ServerInterceptor] = [],
_ body: (InProcessClientTransport, GRPCServer) async throws -> Void
) async throws {
let inProcess = self.makeInProcessPair()
let inProcess = InProcessTransport.makePair()
let server = GRPCServer(
transports: [inProcess.server],
services: services,
Expand Down Expand Up @@ -298,7 +291,7 @@ final class GRPCServerTests: XCTestCase {
}

func testCancelRunningServer() async throws {
let inProcess = self.makeInProcessPair()
let inProcess = InProcessTransport.makePair()
let task = Task {
let server = GRPCServer(transports: [inProcess.server], services: [BinaryEcho()])
try await server.run()
Expand Down Expand Up @@ -353,7 +346,8 @@ final class GRPCServerTests: XCTestCase {

func testRunServerDrainsRunningTransportsWhenOneFailsToStart() async throws {
// Register the in process transport first and allow it to come up.
let inProcess = self.makeInProcessPair()
let inProcess = InProcessTransport.makePair()

// Register a transport waits for a signal before throwing.
let signal = AsyncStream.makeStream(of: Void.self)
let server = GRPCServer(
Expand Down

0 comments on commit 471fe8b

Please sign in to comment.