Browse Source

First pass of conversion from returning to throwing errors.

Only the Echo sample builds.
Tim Burks 9 years ago
parent
commit
8e17a81649

+ 44 - 30
Examples/Echo/Swift/Echo/EchoServer.swift

@@ -64,61 +64,75 @@ class EchoServer {
 
       // NONSTREAMING
       if (requestHandler.method == "/echo.Echo/Get") {
-        _ = requestHandler.receiveMessage(initialMetadata:Metadata())
-        {(requestData) in
-          if let requestData = requestData,
-            let requestMessage =
-            fileDescriptorSet.readMessage("EchoRequest", data: requestData) {
-            requestMessage.forOneField("text") {(field) in
-              let replyMessage = fileDescriptorSet.makeMessage("EchoResponse")!
-              replyMessage.addField("text", value:"Swift nonstreaming echo " + field.string())
-              _ = requestHandler.sendResponse(message:replyMessage.data(),
-                                              trailingMetadata:Metadata())
+
+        do {
+          try requestHandler.receiveMessage(initialMetadata:Metadata())
+          {(requestData) in
+            if let requestData = requestData,
+              let requestMessage =
+              fileDescriptorSet.readMessage("EchoRequest", data: requestData) {
+              try requestMessage.forOneField("text") {(field) in
+                let replyMessage = fileDescriptorSet.makeMessage("EchoResponse")!
+                replyMessage.addField("text", value:"Swift nonstreaming echo " + field.string())
+
+                do {
+                  try requestHandler.sendResponse(message:replyMessage.data(),
+                                                  trailingMetadata:Metadata())
+                } catch (let callError) {
+
+                }
+              }
             }
           }
+        } catch (let callError) {
+
         }
       }
 
       // STREAMING
       if (requestHandler.method == "/echo.Echo/Update") {
-        _ = requestHandler.sendMetadata(
-          initialMetadata: Metadata(),
-          completion: {
+        do {
+          try requestHandler.sendMetadata(
+            initialMetadata: Metadata(),
+            completion: {
 
-            self.handleMessage(
-              fileDescriptorSet: fileDescriptorSet,
-              requestHandler: requestHandler)
+              try self.handleMessage(
+                fileDescriptorSet: fileDescriptorSet,
+                requestHandler: requestHandler)
 
-            // we seem to never get this, but I'm told it's what we're supposed to do
-            _ = requestHandler.receiveClose() {
-              _ = requestHandler.sendStatus(trailingMetadata: Metadata(), completion: {
-                print("status sent")
-                requestHandler.shutdown()
-              })
+              // we seem to never get this, but I'm told it's what we're supposed to do
+              try requestHandler.receiveClose() {
+                try requestHandler.sendStatus(trailingMetadata: Metadata(), completion: {
+                  print("status sent")
+                  requestHandler.shutdown()
+                })
+              }
             }
-          }
-        )
+          )
+        } catch (let callError) {
+
+        }
       }
     }
   }
 
   func handleMessage(fileDescriptorSet: FileDescriptorSet,
-                     requestHandler: Handler) {
-    _ = requestHandler.receiveMessage()
+                     requestHandler: Handler) throws -> Void {
+    try requestHandler.receiveMessage()
       {(requestData) in
         if let requestData = requestData,
           let requestMessage = fileDescriptorSet.readMessage("EchoRequest", data:requestData) {
-          requestMessage.forOneField("text") {(field) in
+          try requestMessage.forOneField("text") {(field) in
             let replyMessage = fileDescriptorSet.makeMessage("EchoResponse")!
             replyMessage.addField("text", value:"Swift streaming echo " + field.string())
-            _ = requestHandler.sendResponse(message:replyMessage.data()) {
+            try requestHandler.sendResponse(message:replyMessage.data()) {
               // after we've sent our response, prepare to handle another message
-              self.handleMessage(fileDescriptorSet:fileDescriptorSet, requestHandler:requestHandler)
+              try self.handleMessage(fileDescriptorSet:fileDescriptorSet, requestHandler:requestHandler)
             }
           }
         } else {
           // if we get an empty message (nil buffer), we close the connection
-          _ = requestHandler.sendStatus(trailingMetadata: Metadata(), completion: {
+          try requestHandler.sendStatus(trailingMetadata: Metadata(), completion: {
             print("status sent")
             requestHandler.shutdown()
           })

+ 28 - 16
Examples/Echo/Swift/Echo/EchoViewController.swift

@@ -55,7 +55,11 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
 
   @IBAction func messageReturnPressed(sender: NSTextField) {
     if enabled {
-      callServer(address:addressField.stringValue)
+      do {
+        try callServer(address:addressField.stringValue)
+      } catch (let callError) {
+
+      }
     }
   }
 
@@ -92,7 +96,7 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     }
   }
 
-  func callServer(address:String) {
+  func callServer(address:String) throws -> Void {
     let requestHost = "example.com"
     let requestMetadata = Metadata(["x-goog-api-key":"YOUR_API_KEY",
                                     "x-ios-bundle-identifier":Bundle.main.bundleIdentifier!])
@@ -112,14 +116,14 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
         guard let call = call else {
           return
         }
-        _ = call.performNonStreamingCall(messageData: requestMessageData,
+        try call.performNonStreamingCall(messageData: requestMessageData,
                                          metadata: requestMetadata)
         { (callResult) in
           print("Received status: \(callResult.statusCode): \(callResult.statusMessage)")
           if let messageData = callResult.resultData,
             let responseMessage = self.fileDescriptorSet.readMessage("EchoResponse",
                                                                      data:messageData) {
-            responseMessage.forOneField("text") {(field) in
+            try responseMessage.forOneField("text") {(field) in
               DispatchQueue.main.async {
                 self.outputField.stringValue = field.string()
               }
@@ -145,7 +149,7 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
         guard let call = call else {
           return
         }
-        _ = call.start(metadata:requestMetadata)
+        try call.start(metadata:requestMetadata)
         self.receiveMessage()
         nowStreaming = true
       }
@@ -166,17 +170,21 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     guard let call = call else {
       return
     }
-    _ = call.receiveMessage() {(data) in
-      guard let responseMessage = self.fileDescriptorSet.readMessage("EchoResponse", data:data)
-        else {
-          return // this stops receiving
-      }
-      responseMessage.forOneField("text") {(field) in
-        DispatchQueue.main.async {
-          self.outputField.stringValue = field.string()
+    do {
+      try call.receiveMessage() {(data) in
+        guard let responseMessage = self.fileDescriptorSet.readMessage("EchoResponse", data:data)
+          else {
+            return // this stops receiving
+        }
+        try responseMessage.forOneField("text") {(field) in
+          DispatchQueue.main.async {
+            self.outputField.stringValue = field.string()
+          }
+          self.receiveMessage()
         }
-        self.receiveMessage()
       }
+    } catch (let callError) {
+
     }
   }
 
@@ -184,8 +192,12 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     guard let call = call else {
       return
     }
-    _ = call.close() {
-      self.nowStreaming = false
+    do {
+      try call.close() {
+        self.nowStreaming = false
+      }
+    } catch (let callError) {
+      
     }
   }
 }

+ 3 - 3
Packages/QuickProto/Sources/FileDescriptor.swift

@@ -62,13 +62,13 @@ class FileDescriptor {
       let messageDescriptor = MessageDescriptor(message: field.message())
       messageDescriptors.append(messageDescriptor)
     }
-    message.forOneField("name") { (field) in
+    try! message.forOneField("name") { (field) in
       name = field.string()
     }
-    message.forOneField("package") { (field) in
+    try! message.forOneField("package") { (field) in
       package = field.string()
     }
-    message.forOneField("syntax") { (field) in
+    try! message.forOneField("syntax") { (field) in
       syntax = field.string()
     }
   }

+ 2 - 2
Packages/QuickProto/Sources/Message.swift

@@ -96,10 +96,10 @@ public class Message {
   }
 
   /// perform an action on one field with the specified name
-  public func forOneField(_ name: String, action:((Field) -> Void)) {
+  public func forOneField(_ name: String, action:((Field) throws -> Void)) throws {
     for field in fields {
       if field.name() == name {
-        action(field)
+        try action(field)
         break
       }
     }

+ 1 - 1
Packages/QuickProto/Sources/MessageDescriptor.swift

@@ -54,7 +54,7 @@ public class MessageDescriptor {
     }
     message.forEachField("options") { (field) in
       let options = field.message()
-      options.forOneField("map_entry") { (field) in
+      try! options.forOneField("map_entry") { (field) in
         if field.bool() {
           optionMapEntry = true
         }

+ 53 - 51
Packages/gRPC/Sources/Call.swift

@@ -107,8 +107,8 @@ public struct CallResult {
   public var trailingMetadata : Metadata?
 }
 
-public typealias CallCompletion = (CallResult) -> Void
-public typealias SendMessageCompletion = (CallError) -> Void
+public typealias CallCompletion = (CallResult) throws -> Void
+public typealias SendMessageCompletion = () -> Void
 
 /// A gRPC API call
 public class Call {
@@ -150,14 +150,15 @@ public class Call {
   ///
   /// - Parameter operations: group of operations to be performed
   /// - Returns: the result of initiating the call
-  func perform(_ operations: OperationGroup)
-    -> CallError {
-      completionQueue.operationGroups[operations.tag] = operations
-      let mutex = CallLock.sharedInstance.mutex
-      mutex.lock()
-      let error = cgrpc_call_perform(underlyingCall, operations.underlyingOperations, operations.tag)
-      mutex.unlock()
-      return CallError.callError(grpcCallError:error)
+  func perform(_ operations: OperationGroup) throws -> Void {
+    completionQueue.operationGroups[operations.tag] = operations
+    let mutex = CallLock.sharedInstance.mutex
+    mutex.lock()
+    let error = cgrpc_call_perform(underlyingCall, operations.underlyingOperations, operations.tag)
+    mutex.unlock()
+    if error != GRPC_CALL_OK {
+      throw CallError.callError(grpcCallError:error)
+    }
   }
 
   /// Performs a nonstreaming gRPC API call
@@ -167,7 +168,7 @@ public class Call {
   /// - Returns: a CallResponse object containing results of the call
   public func performNonStreamingCall(messageData: Data,
                                       metadata: Metadata,
-                                      completion: @escaping CallCompletion) -> CallError {
+                                      completion: @escaping CallCompletion) throws -> Void {
 
     let messageBuffer = ByteBuffer(data:messageData)
 
@@ -188,54 +189,51 @@ public class Call {
                                     completion:
       {(success) in
         if success {
-          completion(CallResult(statusCode:operation_receiveStatusOnClient.status(),
-                                statusMessage:operation_receiveStatusOnClient.statusDetails(),
-                                resultData:operation_receiveMessage.message()?.data(),
-                                initialMetadata:operation_receiveInitialMetadata.metadata(),
-                                trailingMetadata:operation_receiveStatusOnClient.metadata()))
+          try completion(CallResult(statusCode:operation_receiveStatusOnClient.status(),
+                                    statusMessage:operation_receiveStatusOnClient.statusDetails(),
+                                    resultData:operation_receiveMessage.message()?.data(),
+                                    initialMetadata:operation_receiveInitialMetadata.metadata(),
+                                    trailingMetadata:operation_receiveStatusOnClient.metadata()))
         } else {
-          completion(CallResult(statusCode:0,
-                                statusMessage:nil,
-                                resultData:nil,
-                                initialMetadata:nil,
-                                trailingMetadata:nil))
+          try completion(CallResult(statusCode:0,
+                                    statusMessage:nil,
+                                    resultData:nil,
+                                    initialMetadata:nil,
+                                    trailingMetadata:nil))
         }
     })
 
-    return self.perform(operations)
+    try self.perform(operations)
   }
 
   // start a streaming connection
-  public func start(metadata: Metadata) -> CallError {
-    var error : CallError
-    error = self.sendInitialMetadata(metadata: metadata)
-    if error != .ok {
-      return error
-    }
-    error = self.receiveInitialMetadata()
-    if error != .ok {
-      return error
-    }
-    return self.receiveStatus()
+  public func start(metadata: Metadata) throws -> Void {
+    try self.sendInitialMetadata(metadata: metadata)
+    try self.receiveInitialMetadata()
+    try self.receiveStatus()
   }
 
   // send a message over a streaming connection
   public func sendMessage(data: Data,
-                          callback:@escaping SendMessageCompletion = {(error) in })
+                          callback:@escaping SendMessageCompletion = {() in })
     -> Void {
       DispatchQueue.main.async {
         if self.writing {
           self.pendingMessages.append(data) // TODO: return something if we can't accept another message
-          callback(.ok)
+          callback()
         } else {
           self.writing = true
-          let error = self.sendWithoutBlocking(data: data)
-          callback(error)
+          do {
+            try self.sendWithoutBlocking(data: data)
+            callback()
+          } catch (let callError) {
+
+          }
         }
       }
   }
 
-  private func sendWithoutBlocking(data: Data) -> CallError {
+  private func sendWithoutBlocking(data: Data) throws -> Void {
     let messageBuffer = ByteBuffer(data:data)
     let operation_sendMessage = Operation_SendMessage(message:messageBuffer)
     let operations = OperationGroup(call:self, operations:[operation_sendMessage])
@@ -245,7 +243,11 @@ public class Call {
           if self.pendingMessages.count > 0 {
             let nextMessage = self.pendingMessages.first!
             self.pendingMessages.removeFirst()
-            _ = self.sendWithoutBlocking(data: nextMessage)
+            do {
+              try self.sendWithoutBlocking(data: nextMessage)
+            } catch (let callError) {
+
+            }
           } else {
             self.writing = false
           }
@@ -254,26 +256,26 @@ public class Call {
         // TODO: if the event failed, shut down
       }
     }
-    return self.perform(operations)
+    try self.perform(operations)
   }
 
 
   // receive a message over a streaming connection
-  public func receiveMessage(callback:@escaping ((Data!) -> Void)) -> CallError {
+  public func receiveMessage(callback:@escaping ((Data!) throws -> Void)) throws -> Void {
     let operation_receiveMessage = Operation_ReceiveMessage()
     let operations = OperationGroup(call:self, operations:[operation_receiveMessage])
     {(success) in
       if success {
         if let messageBuffer = operation_receiveMessage.message() {
-          callback(messageBuffer.data())
+          try callback(messageBuffer.data())
         }
       }
     }
-    return self.perform(operations)
+    try self.perform(operations)
   }
 
   // send initial metadata over a streaming connection
-  private func sendInitialMetadata(metadata: Metadata) -> CallError {
+  private func sendInitialMetadata(metadata: Metadata) throws -> Void {
     let operation_sendInitialMetadata = Operation_SendInitialMetadata(metadata:metadata);
     let operations = OperationGroup(call:self, operations:[operation_sendInitialMetadata])
     {(success) in
@@ -283,11 +285,11 @@ public class Call {
         return
       }
     }
-    return self.perform(operations)
+    try self.perform(operations)
   }
 
   // receive initial metadata from a streaming connection
-  private func receiveInitialMetadata() -> CallError {
+  private func receiveInitialMetadata() throws -> Void {
     let operation_receiveInitialMetadata = Operation_ReceiveInitialMetadata()
     let operations = OperationGroup(call:self, operations:[operation_receiveInitialMetadata])
     {(success) in
@@ -298,11 +300,11 @@ public class Call {
         }
       }
     }
-    return self.perform(operations)
+    try self.perform(operations)
   }
 
   // receive status from a streaming connection
-  private func receiveStatus() -> CallError {
+  private func receiveStatus() throws -> Void {
     let operation_receiveStatus = Operation_ReceiveStatusOnClient()
     let operations = OperationGroup(call:self,
                                     operations:[operation_receiveStatus])
@@ -311,11 +313,11 @@ public class Call {
         print("status = \(operation_receiveStatus.status()), \(operation_receiveStatus.statusDetails())")
       }
     }
-    return self.perform(operations)
+    try self.perform(operations)
   }
 
   // close a streaming connection
-  public func close(completion:@escaping (() -> Void)) -> CallError {
+  public func close(completion:@escaping (() -> Void)) throws -> Void {
     let operation_sendCloseFromClient = Operation_SendCloseFromClient()
     let operations = OperationGroup(call:self, operations:[operation_sendCloseFromClient])
     {(success) in
@@ -323,6 +325,6 @@ public class Call {
         completion()
       }
     }
-    return self.perform(operations)
+    try self.perform(operations)
   }
 }

+ 5 - 1
Packages/gRPC/Sources/CompletionQueue.swift

@@ -109,7 +109,11 @@ internal class CompletionQueue {
           let tag = cgrpc_event_tag(event)
           if let operationGroup = self.operationGroups[tag] {
             // call the operation group completion handler
-            operationGroup.completion(event.success == 1)
+            do {
+              try operationGroup.completion(event.success == 1)
+            } catch (let callError) {
+
+            }
             self.operationGroups[tag] = nil
           }
           break

+ 23 - 23
Packages/gRPC/Sources/Handler.swift

@@ -100,7 +100,7 @@ public class Handler {
   ///
   /// - Returns: a tuple containing status codes and a message (if available)
   public func receiveMessage(initialMetadata: Metadata,
-                             completion:@escaping ((Data?) -> Void)) -> CallError {
+                             completion:@escaping ((Data?) throws -> Void)) throws -> Void {
     let operation_sendInitialMetadata = Operation_SendInitialMetadata(metadata:initialMetadata);
     let operation_receiveMessage = Operation_ReceiveMessage()
     let operations = OperationGroup(
@@ -110,12 +110,12 @@ public class Handler {
         operation_receiveMessage])
     {(success) in
       if (success) {
-        completion(operation_receiveMessage.message()!.data())
+        try completion(operation_receiveMessage.message()!.data())
       } else {
-        completion(nil)
+        try completion(nil)
       }
     }
-    return call.perform(operations)
+    try call.perform(operations)
   }
 
   /// Sends the response to a request
@@ -123,7 +123,7 @@ public class Handler {
   /// - Parameter message: the message to send
   /// - Returns: a tuple containing status codes
   public func sendResponse(message: Data,
-                           trailingMetadata: Metadata) -> CallError {
+                           trailingMetadata: Metadata) throws -> Void {
     let operation_receiveCloseOnServer = Operation_ReceiveCloseOnServer();
     let operation_sendStatusFromServer = Operation_SendStatusFromServer(status:0,
                                                                         statusDetails:"OK",
@@ -141,7 +141,7 @@ public class Handler {
         self.shutdown()
       }
     }
-    return call.perform(operations)
+    try call.perform(operations)
   }
 
   /// shutdown the handler's completion queue
@@ -151,38 +151,38 @@ public class Handler {
 
   /// Send initial metadata in response to a connection
   public func sendMetadata(initialMetadata: Metadata,
-                           completion:@escaping (() -> Void)) -> CallError {
+                           completion:@escaping (() throws -> Void)) throws -> Void {
     let operation_sendInitialMetadata = Operation_SendInitialMetadata(metadata:initialMetadata);
     let operations = OperationGroup(call:call, operations:[operation_sendInitialMetadata])
     {(success) in
       if success {
-        completion()
+        try completion()
       } else {
-        completion()
+        try completion()
       }
     }
-    return call.perform(operations)
+    try call.perform(operations)
   }
 
   /// Receive the message sent with a call
   ///
   /// - Returns: a tuple containing status codes and a message (if available)
-  public func receiveMessage(completion:(@escaping (Data?) -> Void)) -> CallError {
+  public func receiveMessage(completion:(@escaping (Data?) throws -> Void)) throws -> Void {
     let operation_receiveMessage = Operation_ReceiveMessage()
     let operations = OperationGroup(call:call, operations:[operation_receiveMessage])
     {(success) in
       if success {
         print("server receiveMessage complete")
         if let message = operation_receiveMessage.message() {
-          completion(message.data())
+          try completion(message.data())
         } else {
-          completion(nil)
+          try completion(nil)
         }
       } else {
-        completion(nil)
+        try completion(nil)
       }
     }
-    return call.perform(operations)
+    try call.perform(operations)
   }
 
   /// Sends the response to a request
@@ -190,32 +190,32 @@ public class Handler {
   /// - Parameter message: the message to send
   /// - Returns: a tuple containing status codes
   public func sendResponse(message: Data,
-                           completion: @escaping () -> Void) -> CallError {
+                           completion: @escaping () throws -> Void) throws -> Void {
     let operation_sendMessage = Operation_SendMessage(message:ByteBuffer(data:message))
     let operations = OperationGroup(call:call, operations:[operation_sendMessage])
     {(success) in
       if success {
-        completion()
+        try completion()
       }
     }
-    return call.perform(operations)
+    try call.perform(operations)
   }
 
   /// Recognize when the client has closed a request
-  public func receiveClose(completion: @escaping () -> Void) -> CallError {
+  public func receiveClose(completion: @escaping () throws -> Void) throws -> Void {
     let operation_receiveClose = Operation_ReceiveCloseOnServer()
     let operations = OperationGroup(call:call, operations:[operation_receiveClose])
     {(success) in
       if success {
-        completion()
+        try completion()
       }
     }
-    return call.perform(operations)
+    try call.perform(operations)
   }
 
   /// Send final status to the client
   public func sendStatus(trailingMetadata: Metadata,
-                         completion:@escaping (() -> Void)) -> CallError {
+                         completion:@escaping (() -> Void)) throws -> Void {
     let operation_sendStatusFromServer = Operation_SendStatusFromServer(status:0,
                                                                         statusDetails:"OK",
                                                                         metadata:trailingMetadata)
@@ -225,6 +225,6 @@ public class Handler {
         completion()
       }
     }
-    return call.perform(operations)
+    try call.perform(operations)
   }
 }

+ 3 - 3
Packages/gRPC/Sources/OperationGroup.swift

@@ -62,14 +62,14 @@ class OperationGroup {
   var underlyingOperations : UnsafeMutableRawPointer
 
   /// Completion handler that is called when the group completes
-  var completion : ((Bool) -> Void)
+  var completion : ((Bool) throws -> Void)
 
-  /// Initializes a Operations representation
+  /// Initializes an OperationGroup representation
   ///
   /// - Parameter operations: an array of operations
   init(call: Call,
        operations: [Operation],
-       completion: @escaping ((Bool) -> Void)) {
+       completion: @escaping ((Bool) throws -> Void)) {
     self.call = call
     self.operationsArray = operations
     self.underlyingOperations = cgrpc_operations_create()