Browse Source

cleanup + bug fix in Sessions app

Tim Burks 9 years ago
parent
commit
52096a3aee

+ 11 - 3
Examples/Echo/Swift/Echo/EchoServer.swift

@@ -72,6 +72,8 @@ class EchoServer {
                 let replyMessage = fileDescriptorSet.makeMessage("EchoResponse")!
                 replyMessage.addField("text", value:"Swift nonstreaming echo " + field.string())
                 try requestHandler.sendResponse(message:replyMessage.data(),
+                                                statusCode: 0,
+                                                statusMessage: "OK",
                                                 trailingMetadata:Metadata())
               }
             }
@@ -90,7 +92,10 @@ class EchoServer {
                                     requestHandler:requestHandler)
             // concurrently wait for a close message
             try requestHandler.receiveClose() {
-              try requestHandler.sendStatus(trailingMetadata: Metadata()) {
+              try requestHandler.sendStatus(statusCode: 0,
+                                            statusMessage:"OK",
+                                            trailingMetadata: Metadata())
+              {
                 requestHandler.shutdown()
               }
             }
@@ -117,9 +122,12 @@ class EchoServer {
         }
       } else {
         // if we get an empty message (requestData == nil), we close the connection
-        try requestHandler.sendStatus(trailingMetadata: Metadata(), completion: {
+        try requestHandler.sendStatus(statusCode: 0,
+                                      statusMessage: "OK",
+                                      trailingMetadata: Metadata())
+        {
           requestHandler.shutdown()
-        })
+        }
       }
     }
   }

+ 1 - 1
Examples/Echo/Swift/Echo/EchoViewController.swift

@@ -118,7 +118,7 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
         guard let call = call else {
           return
         }
-        try call.performNonStreamingCall(messageData: requestMessageData,
+        try call.performNonStreamingCall(message: requestMessageData,
                                          metadata: requestMetadata)
         {(callResult) in
           print("Received status: \(callResult.statusCode): \(callResult.statusMessage)")

+ 6 - 7
Examples/Sessions/Sessions/Document.swift

@@ -172,7 +172,7 @@ class Document: NSDocument {
                                  ["z": "zither"]])
 
         do {
-          try call.performNonStreamingCall(messageData: messageData!,
+          try call.performNonStreamingCall(message: messageData!,
                                            metadata: metadata)
           {(callResult) in
 
@@ -187,7 +187,7 @@ class Document: NSDocument {
             if callResult.statusCode != 0 {
               self.setIsRunning(false)
             }
-            if let messageData = messageData {
+            if let messageData = callResult.resultData {
               let messageString = String(data: messageData as Data, encoding: .utf8)
               self.log("\(i): Received message: " + messageString!)
             }
@@ -200,7 +200,7 @@ class Document: NSDocument {
             }
           }
         } catch (let callError) {
-
+          Swift.print("call error \(callError)")
         }
         self.log("------------------------------")
         sleep(1)
@@ -228,7 +228,6 @@ class Document: NSDocument {
           + " from " + requestHandler.caller)
 
         let initialMetadata = requestHandler.requestMetadata
-
         for i in 0..<initialMetadata.count() {
           self.log("\(requestCount): Received initial metadata -> " + initialMetadata.key(index:i)
             + ":" + initialMetadata.value(index:i))
@@ -248,17 +247,17 @@ class Document: NSDocument {
         }
 
         let replyMessage = "hello, client!"
-
         let trailingMetadataToSend = Metadata([["0": "zero"],
                                                ["1": "one"],
                                                ["2": "two"]])
-
         try requestHandler.sendResponse(message:replyMessage.data(using: .utf8)!,
+                                        statusCode:0,
+                                        statusMessage:"OK",
                                         trailingMetadata:trailingMetadataToSend)
 
         self.log("------------------------------")
       } catch (let callError) {
-        
+        Swift.print("call error \(callError)")
       }
     }
     

+ 4 - 4
Packages/gRPC/Sources/Call.swift

@@ -164,13 +164,13 @@ public class Call {
 
   /// Performs a nonstreaming gRPC API call
   ///
-  /// - Parameter message: a ByteBuffer containing the message to send
+  /// - Parameter message: data containing the message to send
   /// - Parameter metadata: metadata to send with the call
-  /// - Returns: a CallResponse object containing results of the call
-  public func performNonStreamingCall(messageData: Data,
+  /// - Parameter callback: a blocko to call with a CallResponse object containing call results
+  public func performNonStreamingCall(message: Data,
                                       metadata: Metadata,
                                       completion: @escaping CallCompletion) throws -> Void {
-    let messageBuffer = ByteBuffer(data:messageData)
+    let messageBuffer = ByteBuffer(data:message)
     let operations = OperationGroup(call:self,
                                     operations:[.sendInitialMetadata(metadata),
                                                 .sendMessage(messageBuffer),

+ 27 - 10
Packages/gRPC/Sources/Handler.swift

@@ -90,15 +90,15 @@ public class Handler {
   ///
   /// Fills the handler properties with information about the received request
   ///
-  /// - Returns: a CallError indicating the result of requesting the call
-  func requestCall(tag: Int) -> CallError {
+  func requestCall(tag: Int) throws -> Void {
     let error = cgrpc_handler_request_call(underlyingHandler, requestMetadata.underlyingArray, tag)
-    return CallError.callError(grpcCallError: error)
+    if error != GRPC_CALL_OK {
+      throw CallError.callError(grpcCallError: error)
+    }
   }
 
   /// Receive the message sent with a call
   ///
-  /// - Returns: a tuple containing status codes and a message (if available)
   public func receiveMessage(initialMetadata: Metadata,
                              completion:@escaping ((Data?) throws -> Void)) throws -> Void {
     let operations = OperationGroup(
@@ -119,15 +119,17 @@ public class Handler {
   /// Sends the response to a request
   ///
   /// - Parameter message: the message to send
-  /// - Returns: a tuple containing status codes
+  /// - Parameter trailingMetadata: trailing metadata to send
   public func sendResponse(message: Data,
+                           statusCode: Int,
+                           statusMessage: String,
                            trailingMetadata: Metadata) throws -> Void {
     let messageBuffer = ByteBuffer(data:message)
     let operations = OperationGroup(
       call:call,
       operations:[
         .receiveCloseOnServer,
-        .sendStatusFromServer(0, "OK", trailingMetadata),
+        .sendStatusFromServer(statusCode, statusMessage, trailingMetadata),
         .sendMessage(messageBuffer)])
     {(operationGroup) in
       if operationGroup.success {
@@ -137,12 +139,15 @@ public class Handler {
     try call.perform(operations)
   }
 
-  /// shutdown the handler's completion queue
+  /// Shutdown the handler's completion queue
   public func shutdown() {
     completionQueue.shutdown()
   }
 
   /// Send initial metadata in response to a connection
+  ///
+  /// - Parameter initialMetadata: initial metadata to send
+  /// - Parameter completion: a completion handler to call after the metadata has been sent
   public func sendMetadata(initialMetadata: Metadata,
                            completion:@escaping (() throws -> Void)) throws -> Void {
     let operations = OperationGroup(call:call,
@@ -159,6 +164,7 @@ public class Handler {
 
   /// Receive the message sent with a call
   ///
+  /// - Parameter completion: a completion handler to call after the message has been received
   /// - Returns: a tuple containing status codes and a message (if available)
   public func receiveMessage(completion:(@escaping (Data?) throws -> Void)) throws -> Void {
     let operations = OperationGroup(call:call, operations:[.receiveMessage])
@@ -179,7 +185,7 @@ public class Handler {
   /// Sends the response to a request
   ///
   /// - Parameter message: the message to send
-  /// - Returns: a tuple containing status codes
+  /// - Parameter completion: a completion handler to call after the response has been sent
   public func sendResponse(message: Data,
                            completion: @escaping () throws -> Void) throws -> Void {
     let operations = OperationGroup(call:call,
@@ -193,6 +199,8 @@ public class Handler {
   }
 
   /// Recognize when the client has closed a request
+  ///
+  /// - Parameter completion: a completion handler to call after request has been closed
   public func receiveClose(completion: @escaping () throws -> Void) throws -> Void {
     let operations = OperationGroup(call:call,
                                     operations:[.receiveCloseOnServer])
@@ -205,10 +213,19 @@ public class Handler {
   }
 
   /// Send final status to the client
-  public func sendStatus(trailingMetadata: Metadata,
+  ///
+  /// - Parameter statusCode: status code to send
+  /// - Parameter statusMessage: status message to send
+  /// - Parameter trailingMetadata: trailing metadata to send
+  /// - Parameter completion: a completion handler to call after the status has been sent
+  public func sendStatus(statusCode: Int,
+                         statusMessage: String,
+                         trailingMetadata: Metadata,
                          completion:@escaping (() -> Void)) throws -> Void {
     let operations = OperationGroup(call:call,
-                                    operations:[.sendStatusFromServer(0, "OK", trailingMetadata)])
+                                    operations:[.sendStatusFromServer(statusCode,
+                                                                      statusMessage,
+                                                                      trailingMetadata)])
     {(operationGroup) in
       if operationGroup.success {
         completion()

+ 22 - 43
Packages/gRPC/Sources/Server.swift

@@ -77,30 +77,31 @@ public class Server {
     DispatchQueue.global().async {
       var running = true
       while(running) {
-        let handler = Handler(underlyingServer:self.underlyingServer)
-        let call_error = handler.requestCall(tag:101)
-        if (call_error != .ok) {
-          // not good, let's break
-          break
-        }
-        // block while waiting for an incoming request
-        let event = self.completionQueue.wait(timeout:600)
-        if (event.type == .complete) {
-          if event.tag == 101 {
-            // run the handler and remove it when it finishes
-            if event.success != 0 {
-              self.handlers.add(handler)
-              handler.completionQueue.runToCompletion() {
-                self.handlers.remove(handler)
+        do {
+          let handler = Handler(underlyingServer:self.underlyingServer)
+          try handler.requestCall(tag:101)
+          // block while waiting for an incoming request
+          let event = self.completionQueue.wait(timeout:600)
+          if (event.type == .complete) {
+            if event.tag == 101 {
+              // run the handler and remove it when it finishes
+              if event.success != 0 {
+                self.handlers.add(handler)
+                handler.completionQueue.runToCompletion() {
+                  self.handlers.remove(handler)
+                }
+                handlerFunction(handler)
               }
-              handlerFunction(handler)
+            } else if event.tag == 0 {
+              running = false // exit the loop
             }
-          } else if event.tag == 0 {
-            running = false // exit the loop
+          } else if (event.type == .queueTimeout) {
+            // everything is fine
+          } else if (event.type == .queueShutdown) {
+            running = false
           }
-        } else if (event.type == .queueTimeout) {
-          // everything is fine
-        } else if (event.type == .queueShutdown) {
+        } catch (let callError) {
+          print("server call error: \(callError)")
           running = false
         }
       }
@@ -117,26 +118,4 @@ public class Server {
   public func onCompletion(completion:@escaping (() -> Void)) -> Void {
     onCompletion = completion
   }
-
-  /// Gets the next request sent to the server
-  ///
-  /// - Returns: a tuple containing the results of waiting and a possible Handler for the request
-  private func getNextRequest(timeout: TimeInterval) -> (CallError, CompletionType, Handler?) {
-    let handler = Handler(underlyingServer:self.underlyingServer)
-    let call_error = handler.requestCall(tag:101)
-    if (call_error != .ok) {
-      return (call_error, .complete, nil)
-    } else {
-      let event = self.completionQueue.wait(timeout:timeout)
-      if (event.type == .complete) {
-        handler.completionQueue.runToCompletion() {
-          self.handlers.remove(handler)
-        }
-        self.handlers.add(handler)
-        return (.ok, .complete, handler)
-      } else {
-        return (.ok, event.type, nil)
-      }
-    }
-  }
 }