Browse Source

Rename 'GRPCClient.run()' (#2156)

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
George Barnett 1 year ago
parent
commit
eafb3341cc

+ 11 - 6
Sources/GRPCCore/GRPCClient.swift

@@ -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 ``runConnections()`` 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 ``runConnections()`` 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
@@ -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 'runConnections()'. Transports should tolerate
         // queuing the request if not yet started.
         ()
       case .stopping, .stopped:
@@ -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 runConnections() async throws {
     try self.stateMachine.withLock { try $0.state.run() }
 
     // When this function exits the client must have stopped.
@@ -227,6 +227,11 @@ public final class GRPCClient: Sendable {
     }
   }
 
+  @available(*, deprecated, renamed: "runConnections", message: "It'll be removed before v2.")
+  public func run() async throws {
+    try await self.runConnections()
+  }
+
   /// Close the client.
   ///
   /// The transport will be closed: this means that it will be given enough time to wait for
@@ -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: ``runConnections()`` must have been called and still executing, and ``beginGracefulShutdown()`` mustn't
   /// have been called.
   ///
   /// - Parameters:
@@ -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.runConnections()
     }
 
     let result = try await handleClient(client)

+ 6 - 6
Tests/GRPCCoreTests/GRPCClientTests.swift

@@ -336,7 +336,7 @@ final class GRPCClientTests: XCTestCase {
       }
 
       group.addTask {
-        try await client.run()
+        try await client.runConnections()
       }
 
       // Wait for client and server to be running.
@@ -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.runConnections() }
     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.runConnections()
     } errorHandler: { error in
       XCTAssertEqual(error.code, .clientIsStopped)
     }
@@ -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.runConnections() }
     // 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.runConnections()
     } errorHandler: { error in
       XCTAssertEqual(error.code, .clientIsAlreadyRunning)
     }
@@ -551,7 +551,7 @@ struct ClientTests {
       }
 
       group.addTask {
-        try await client.run()
+        try await client.runConnections()
       }
 
       // Make sure both server and client are running

+ 2 - 2
Tests/GRPCInProcessTransportTests/InProcessTransportTests.swift

@@ -35,7 +35,7 @@ struct InProcessTransportTests {
 
       let client = GRPCClient(transport: inProcess.client)
       group.addTask {
-        try await client.run()
+        try await client.runConnections()
       }
 
       try await execute(server, client)
@@ -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 runConnections() method returns.
       client.beginGracefulShutdown()
     }
   }