Browse Source

Update RouteGuide examples (#1426)

George Barnett 3 years ago
parent
commit
31b7551c5f

+ 0 - 1
Sources/Examples/HelloWorld/Client/main.swift

@@ -67,5 +67,4 @@ struct HelloWorld: AsyncParsableCommand {
     }
   }
 }
-
 #endif // compiler(>=5.6)

+ 0 - 1
Sources/Examples/HelloWorld/Server/main.swift

@@ -43,5 +43,4 @@ struct HelloWorld: AsyncParsableCommand {
     try await server.onClose.get()
   }
 }
-
 #endif // compiler(>=5.6)

+ 17 - 0
Sources/Examples/RouteGuide/Client/Empty.swift

@@ -0,0 +1,17 @@
+/*
+ * Copyright 2022, 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.
+ */
+
+// This file exists to workaround https://github.com/apple/swift/issues/55127.

+ 34 - 54
Sources/Examples/RouteGuide/Client/main.swift → Sources/Examples/RouteGuide/Client/RouteGuideClient.swift

@@ -32,20 +32,8 @@ func loadFeatures() throws -> [Routeguide_Feature] {
   return try Routeguide_Feature.array(fromJSONUTF8Data: data)
 }
 
-/// Makes a `RouteGuide` client for a service hosted on "localhost" and listening on the given port.
 @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
-func makeClient(port: Int, group: EventLoopGroup) throws -> Routeguide_RouteGuideAsyncClient {
-  let channel = try GRPCChannelPool.with(
-    target: .host("localhost", port: port),
-    transportSecurity: .plaintext,
-    eventLoopGroup: group
-  )
-
-  return Routeguide_RouteGuideAsyncClient(channel: channel)
-}
-
-@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
-internal struct RouteGuideExample: @unchecked Sendable {
+internal struct RouteGuideExample {
   private let routeGuide: Routeguide_RouteGuideAsyncClient
   private let features: [Routeguide_Feature]
 
@@ -54,37 +42,26 @@ internal struct RouteGuideExample: @unchecked Sendable {
     self.features = features
   }
 
-  func runAndBlockUntilCompletion() {
-    let group = DispatchGroup()
-    group.enter()
-
-    Task {
-      defer {
-        group.leave()
-      }
-
-      // Look for a valid feature.
-      await self.getFeature(latitude: 409_146_138, longitude: -746_188_906)
+  func run() async {
+    // Look for a valid feature.
+    await self.getFeature(latitude: 409_146_138, longitude: -746_188_906)
 
-      // Look for a missing feature.
-      await self.getFeature(latitude: 0, longitude: 0)
-
-      // Looking for features between 40, -75 and 42, -73.
-      await self.listFeatures(
-        lowLatitude: 400_000_000,
-        lowLongitude: -750_000_000,
-        highLatitude: 420_000_000,
-        highLongitude: -730_000_000
-      )
+    // Look for a missing feature.
+    await self.getFeature(latitude: 0, longitude: 0)
 
-      // Record a few randomly selected points from the features file.
-      await self.recordRoute(features: features, featuresToVisit: 10)
+    // Looking for features between 40, -75 and 42, -73.
+    await self.listFeatures(
+      lowLatitude: 400_000_000,
+      lowLongitude: -750_000_000,
+      highLatitude: 420_000_000,
+      highLongitude: -730_000_000
+    )
 
-      // Send and receive some notes.
-      await self.routeChat()
-    }
+    // Record a few randomly selected points from the features file.
+    await self.recordRoute(features: self.features, featuresToVisit: 10)
 
-    group.wait()
+    // Send and receive some notes.
+    await self.routeChat()
   }
 }
 
@@ -229,12 +206,13 @@ extension RouteGuideExample {
   }
 }
 
+@main
 @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
-struct RouteGuide: ParsableCommand {
+struct RouteGuide: AsyncParsableCommand {
   @Option(help: "The port to connect to")
   var port: Int = 1234
 
-  func run() throws {
+  func run() async throws {
     // Load the features.
     let features = try loadFeatures()
 
@@ -243,15 +221,18 @@ struct RouteGuide: ParsableCommand {
       try? group.syncShutdownGracefully()
     }
 
-    let routeGuide = try makeClient(port: self.port, group: group)
+    let channel = try GRPCChannelPool.with(
+      target: .host("localhost", port: self.port),
+      transportSecurity: .plaintext,
+      eventLoopGroup: group
+    )
     defer {
-      try? routeGuide.channel.close().wait()
+      try? channel.close().wait()
     }
 
-    // ArgumentParser did not support async/await at the point in time this was written. Block
-    // this thread while the example runs.
+    let routeGuide = Routeguide_RouteGuideAsyncClient(channel: channel)
     let example = RouteGuideExample(routeGuide: routeGuide, features: features)
-    example.runAndBlockUntilCompletion()
+    await example.run()
   }
 }
 
@@ -266,12 +247,11 @@ extension Routeguide_Feature: CustomStringConvertible {
     return "\(self.name) at \(self.location)"
   }
 }
-
-if #available(macOS 12, *) {
-  RouteGuide.main()
-} else {
-  fatalError("The RouteGuide example requires macOS 12 or newer.")
-}
 #else
-fatalError("The RouteGuide example requires Swift concurrency features.")
+@main
+enum NotAvailable {
+  static func main() {
+    print("This example requires Swift >= 5.6")
+  }
+}
 #endif // compiler(>=5.6)

+ 13 - 18
Sources/Examples/RouteGuide/Server/main.swift → Sources/Examples/RouteGuide/Server/RouteGuideServer.swift

@@ -33,12 +33,13 @@ func loadFeatures() throws -> [Routeguide_Feature] {
   return try Routeguide_Feature.array(fromJSONUTF8Data: data)
 }
 
+@main
 @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
-struct RouteGuide: ParsableCommand {
+struct RouteGuide: AsyncParsableCommand {
   @Option(help: "The port to listen on for new connections")
   var port = 1234
 
-  func run() throws {
+  func run() async throws {
     // Create an event loop group for the server to run on.
     let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
     defer {
@@ -52,28 +53,22 @@ struct RouteGuide: ParsableCommand {
     let provider = RouteGuideProvider(features: features)
 
     // Start the server and print its address once it has started.
-    let server = Server.insecure(group: group)
+    let server = try await Server.insecure(group: group)
       .withServiceProviders([provider])
       .bind(host: "localhost", port: self.port)
+      .get()
 
-    server.map {
-      $0.channel.localAddress
-    }.whenSuccess { address in
-      print("server started on port \(address!.port!)")
-    }
+    print("server started on port \(server.channel.localAddress!.port!)")
 
     // Wait on the server's `onClose` future to stop the program from exiting.
-    _ = try server.flatMap {
-      $0.onClose
-    }.wait()
+    try await server.onClose.get()
   }
 }
-
-if #available(macOS 12, *) {
-  RouteGuide.main()
-} else {
-  fatalError("The RouteGuide example requires macOS 12 or newer.")
-}
 #else
-fatalError("The RouteGuide example requires Swift concurrency support.")
+@main
+enum RouteGuide {
+  static func main() {
+    print("This example requires Swift >= 5.6")
+  }
+}
 #endif // compiler(>=5.6)