Skip to content

Commit

Permalink
Rename 'GRPCClient.run()'
Browse files Browse the repository at this point in the history
Motivation:

To support swift-service-lifecycle the grpc client and server types will
conform to its 'Service' protocol. This has a requirement for a method
called 'run()'. Ideally this would respect graceful shutdown. We can't
do this with the current client as we already have a run method. To do
this we'd need to wrap the type and redeclare all of it's methods. Using
a wrapper isn't a good user experience.

Modifications:

- Rename run to 'maintainConnections()'
- Deprecate 'run()', we'll remove this later

Result:

- run is deprecated
  • Loading branch information
glbrntt committed Jan 14, 2025
1 parent 76073a2 commit c5cf12b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
17 changes: 11 additions & 6 deletions Sources/GRPCCore/GRPCClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ private import Synchronization
/// ## Creating a client manually
///
/// If the `with`-style methods for creating clients isn't suitable for your application then you
/// can create and run a client manually. This requires you to call the ``run()`` method in a task
/// can create and run a client manually. This requires you to call the ``maintainConnections()`` method in a task
/// which instructs the client to start connecting to the server.
///
/// The ``run()`` method won't return until the client has finished handling all requests. You can
/// The ``maintainConnections()`` method won't return until the client has finished handling all requests. You can
/// signal to the client that it should stop creating new request streams by calling ``beginGracefulShutdown()``.
/// This gives the client enough time to drain any requests already in flight. To stop the client
/// more abruptly you can cancel the task running your client. If your application requires
Expand Down Expand Up @@ -114,7 +114,7 @@ public final class GRPCClient: Sendable {
func checkExecutable() throws {
switch self {
case .notStarted, .running:
// Allow .notStarted as making a request can race with 'run()'. Transports should tolerate
// Allow .notStarted as making a request can race with 'maintainConnections()'. Transports should tolerate
// queuing the request if not yet started.
()
case .stopping, .stopped:
Expand Down Expand Up @@ -208,7 +208,7 @@ public final class GRPCClient: Sendable {
///
/// The client, and by extension this function, can only be run once. If the client is already
/// running or has already been closed then a ``RuntimeError`` is thrown.
public func run() async throws {
public func maintainConnections() async throws {
try self.stateMachine.withLock { try $0.state.run() }

// When this function exits the client must have stopped.
Expand All @@ -227,6 +227,11 @@ public final class GRPCClient: Sendable {
}
}

@available(*, deprecated, renamed: "maintainConnections", message: "It'll be removed before v2.")
public func run() async throws {
try await self.maintainConnections()
}

/// Close the client.
///
/// The transport will be closed: this means that it will be given enough time to wait for
Expand Down Expand Up @@ -338,7 +343,7 @@ public final class GRPCClient: Sendable {

/// Start a bidirectional streaming RPC.
///
/// - Note: ``run()`` must have been called and still executing, and ``beginGracefulShutdown()`` mustn't
/// - Note: ``maintainConnections()`` must have been called and still executing, and ``beginGracefulShutdown()`` mustn't
/// have been called.
///
/// - Parameters:
Expand Down Expand Up @@ -430,7 +435,7 @@ public func withGRPCClient<Result: Sendable>(
try await withThrowingDiscardingTaskGroup { group in
let client = GRPCClient(transport: transport, interceptorPipeline: interceptorPipeline)
group.addTask {
try await client.run()
try await client.maintainConnections()
}

let result = try await handleClient(client)
Expand Down
12 changes: 6 additions & 6 deletions Tests/GRPCCoreTests/GRPCClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ final class GRPCClientTests: XCTestCase {
}

group.addTask {
try await client.run()
try await client.maintainConnections()
}

// Wait for client and server to be running.
Expand Down Expand Up @@ -377,13 +377,13 @@ final class GRPCClientTests: XCTestCase {
let inProcess = InProcessTransport()
let client = GRPCClient(transport: inProcess.client)
// Run the client.
let task = Task { try await client.run() }
let task = Task { try await client.maintainConnections() }
task.cancel()
try await task.value

// Client is stopped, should throw an error.
await XCTAssertThrowsErrorAsync(ofType: RuntimeError.self) {
try await client.run()
try await client.maintainConnections()
} errorHandler: { error in
XCTAssertEqual(error.code, .clientIsStopped)
}
Expand All @@ -393,13 +393,13 @@ final class GRPCClientTests: XCTestCase {
let inProcess = InProcessTransport()
let client = GRPCClient(transport: inProcess.client)
// Run the client.
let task = Task { try await client.run() }
let task = Task { try await client.maintainConnections() }
// Make sure the client is run for the first time here.
try await Task.sleep(for: .milliseconds(10))

// Client is already running, should throw an error.
await XCTAssertThrowsErrorAsync(ofType: RuntimeError.self) {
try await client.run()
try await client.maintainConnections()
} errorHandler: { error in
XCTAssertEqual(error.code, .clientIsAlreadyRunning)
}
Expand Down Expand Up @@ -551,7 +551,7 @@ struct ClientTests {
}

group.addTask {
try await client.run()
try await client.maintainConnections()
}

// Make sure both server and client are running
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct InProcessTransportTests {

let client = GRPCClient(transport: inProcess.client)
group.addTask {
try await client.run()
try await client.maintainConnections()
}

try await execute(server, client)
Expand All @@ -60,7 +60,7 @@ struct InProcessTransportTests {
#expect(messages == ["isCancelled=true"])
}

// Finally, shutdown the client so its run() method returns.
// Finally, shutdown the client so its maintainConnections() method returns.
client.beginGracefulShutdown()
}
}
Expand Down

0 comments on commit c5cf12b

Please sign in to comment.