Browse Source

Hide grpc_call_error and grpc_event.

Tim Burks 9 years ago
parent
commit
0fb162af68

+ 79 - 24
Packages/gRPC/Sources/Call.swift

@@ -44,6 +44,61 @@ private class CallLock {
   static let sharedInstance = CallLock()
 }
 
+public enum CallError : Error {
+  case ok
+  case unknown
+  case notOnServer
+  case notOnClient
+  case alreadyAccepted
+  case alreadyInvoked
+  case notInvoked
+  case alreadyFinished
+  case tooManyOperations
+  case invalidFlags
+  case invalidMetadata
+  case invalidMessage
+  case notServerCompletionQueue
+  case batchTooBig
+  case payloadTypeMismatch
+
+  static func callError(grpcCallError error: grpc_call_error) -> CallError {
+    switch(error) {
+    case GRPC_CALL_OK:
+      return .ok
+    case GRPC_CALL_ERROR:
+      return .unknown
+    case GRPC_CALL_ERROR_NOT_ON_SERVER:
+      return .notOnServer
+    case GRPC_CALL_ERROR_NOT_ON_CLIENT:
+      return .notOnClient
+    case GRPC_CALL_ERROR_ALREADY_ACCEPTED:
+      return .alreadyAccepted
+    case GRPC_CALL_ERROR_ALREADY_INVOKED:
+      return .alreadyInvoked
+    case GRPC_CALL_ERROR_NOT_INVOKED:
+      return .notInvoked
+    case GRPC_CALL_ERROR_ALREADY_FINISHED:
+      return .alreadyFinished
+    case GRPC_CALL_ERROR_TOO_MANY_OPERATIONS:
+      return .tooManyOperations
+    case GRPC_CALL_ERROR_INVALID_FLAGS:
+      return .invalidFlags
+    case GRPC_CALL_ERROR_INVALID_METADATA:
+      return .invalidMetadata
+    case GRPC_CALL_ERROR_INVALID_MESSAGE:
+      return .invalidMessage
+    case GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE:
+      return .notServerCompletionQueue
+    case GRPC_CALL_ERROR_BATCH_TOO_BIG:
+      return .batchTooBig
+    case GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH:
+      return .payloadTypeMismatch
+    default:
+      return .unknown
+    }
+  }
+}
+
 public struct CallResult {
   public var statusCode : Int
   public var statusMessage : String?
@@ -53,7 +108,7 @@ public struct CallResult {
 }
 
 public typealias CallCompletion = (CallResult) -> Void
-public typealias SendMessageCompletion = (grpc_call_error) -> Void
+public typealias SendMessageCompletion = (CallError) -> Void
 
 /// A gRPC API call
 public class Call {
@@ -99,12 +154,12 @@ public class Call {
   func performOperations(operations: OperationGroup,
                          tag: Int64,
                          completionQueue: CompletionQueue)
-    -> grpc_call_error {
+    -> CallError {
       let mutex = CallLock.sharedInstance.mutex
       mutex.lock()
       let error = cgrpc_call_perform(underlyingCall, operations.operations, tag)
       mutex.unlock()
-      return error
+      return CallError.callError(grpcCallError:error)
   }
 
   /// Performs a nonstreaming gRPC API call
@@ -114,7 +169,7 @@ public class Call {
   /// - Returns: a CallResponse object containing results of the call
   public func performNonStreamingCall(messageData: Data,
                                       metadata: Metadata,
-                                      completion: @escaping CallCompletion) -> grpc_call_error {
+                                      completion: @escaping CallCompletion) -> CallError {
 
     let messageBuffer = ByteBuffer(data:messageData)
 
@@ -153,7 +208,7 @@ public class Call {
   }
 
   // perform a group of operations (used internally)
-  private func perform(operations: OperationGroup) -> grpc_call_error {
+  private func perform(operations: OperationGroup) -> CallError {
     self.completionQueue.operationGroups[operations.tag] = operations
     return performOperations(operations:operations,
                              tag:operations.tag,
@@ -161,14 +216,14 @@ public class Call {
   }
 
   // start a streaming connection
-  public func start(metadata: Metadata) -> grpc_call_error {
-    var error : grpc_call_error
+  public func start(metadata: Metadata) -> CallError {
+    var error : CallError
     error = self.sendInitialMetadata(metadata: metadata)
-    if error != GRPC_CALL_OK {
+    if error != .ok {
       return error
     }
     error = self.receiveInitialMetadata()
-    if error != GRPC_CALL_OK {
+    if error != .ok {
       return error
     }
     return self.receiveStatus()
@@ -178,19 +233,19 @@ public class Call {
   public func sendMessage(data: Data,
                           callback:@escaping SendMessageCompletion = {(error) in })
     -> Void {
-    DispatchQueue.main.async {
-      if self.writing {
-        self.pendingMessages.append(data) // TODO: return something if we can't accept another message
-        callback(GRPC_CALL_OK)
-      } else {
-        self.writing = true
-        let error = self.sendWithoutBlocking(data: data)
-        callback(error)
+      DispatchQueue.main.async {
+        if self.writing {
+          self.pendingMessages.append(data) // TODO: return something if we can't accept another message
+          callback(.ok)
+        } else {
+          self.writing = true
+          let error = self.sendWithoutBlocking(data: data)
+          callback(error)
+        }
       }
-    }
   }
 
-  private func sendWithoutBlocking(data: Data) -> grpc_call_error {
+  private func sendWithoutBlocking(data: Data) -> CallError {
     let messageBuffer = ByteBuffer(data:data)
     let operation_sendMessage = Operation_SendMessage(message:messageBuffer)
     let operations = OperationGroup(call:self, operations:[operation_sendMessage])
@@ -213,7 +268,7 @@ public class Call {
 
 
   // receive a message over a streaming connection
-  public func receiveMessage(callback:@escaping ((Data!) -> Void)) -> grpc_call_error {
+  public func receiveMessage(callback:@escaping ((Data!) -> Void)) -> CallError {
     let operation_receiveMessage = Operation_ReceiveMessage()
     let operations = OperationGroup(call:self, operations:[operation_receiveMessage])
     { (event) in
@@ -225,7 +280,7 @@ public class Call {
   }
 
   // send initial metadata over a streaming connection
-  private func sendInitialMetadata(metadata: Metadata) -> grpc_call_error {
+  private func sendInitialMetadata(metadata: Metadata) -> CallError {
     let operation_sendInitialMetadata = Operation_SendInitialMetadata(metadata:metadata);
     let operations = OperationGroup(call:self, operations:[operation_sendInitialMetadata])
     { (success) in
@@ -239,7 +294,7 @@ public class Call {
   }
 
   // receive initial metadata from a streaming connection
-  private func receiveInitialMetadata() -> grpc_call_error {
+  private func receiveInitialMetadata() -> CallError {
     let operation_receiveInitialMetadata = Operation_ReceiveInitialMetadata()
     let operations = OperationGroup(call:self, operations:[operation_receiveInitialMetadata])
     { (event) in
@@ -252,7 +307,7 @@ public class Call {
   }
 
   // receive status from a streaming connection
-  private func receiveStatus() -> grpc_call_error {
+  private func receiveStatus() -> CallError {
     let operation_receiveStatus = Operation_ReceiveStatusOnClient()
     let operations = OperationGroup(call:self,
                                     operations:[operation_receiveStatus])
@@ -263,7 +318,7 @@ public class Call {
   }
 
   // close a streaming connection
-  public func close(completion:@escaping (() -> Void)) -> grpc_call_error {
+  public func close(completion:@escaping (() -> Void)) -> CallError {
     let operation_sendCloseFromClient = Operation_SendCloseFromClient()
     let operations = OperationGroup(call:self, operations:[operation_sendCloseFromClient])
     { (event) in

+ 35 - 2
Packages/gRPC/Sources/CompletionQueue.swift

@@ -35,6 +35,38 @@
 #endif
 import Foundation
 
+public enum CompletionType {
+  case queueShutdown
+  case queueTimeout
+  case complete
+  case unknown
+
+  static func completionType(grpcCompletionType value: grpc_completion_type) -> CompletionType {
+    switch(value) {
+    case GRPC_QUEUE_SHUTDOWN:
+      return .queueShutdown
+    case GRPC_QUEUE_TIMEOUT:
+      return .queueTimeout
+    case GRPC_OP_COMPLETE:
+      return .complete
+    default:
+      return .unknown
+    }
+  }
+}
+
+public struct CompletionEvent {
+  public var type: CompletionType
+  public var success: Int32
+  public var tag: Int64
+
+  init(_ event: grpc_event) {
+    type = CompletionType.completionType(grpcCompletionType: event.type)
+    success = event.success
+    tag = cgrpc_event_tag(event)
+  }
+}
+
 /// A gRPC Completion Queue
 class CompletionQueue {
 
@@ -57,8 +89,9 @@ class CompletionQueue {
   ///
   /// - Parameter timeout: a timeout value in seconds
   /// - Returns: a grpc_completion_type code indicating the result of waiting
-  public func waitForCompletion(timeout: Double) -> grpc_event {
-    return cgrpc_completion_queue_get_next_event(underlyingCompletionQueue, timeout);
+  public func waitForCompletion(timeout: Double) -> CompletionEvent {
+    let event = cgrpc_completion_queue_get_next_event(underlyingCompletionQueue, timeout);
+    return CompletionEvent(event)
   }
 
   /// Run a completion queue

+ 4 - 3
Packages/gRPC/Sources/Handler.swift

@@ -94,9 +94,10 @@ public class Handler {
   ///
   /// Fills the handler properties with information about the received request
   ///
-  /// - Returns: a grpc_call_error indicating the result of requesting the call
-  func requestCall(tag: Int) -> grpc_call_error {
-    return cgrpc_handler_request_call(underlyingHandler, requestMetadata.array, tag)
+  /// - Returns: a CallError indicating the result of requesting the call
+  func requestCall(tag: Int) -> CallError {
+    let error = cgrpc_handler_request_call(underlyingHandler, requestMetadata.array, tag)
+    return CallError.callError(grpcCallError: error)
   }
 
   /// Receive the message sent with a call

+ 12 - 12
Packages/gRPC/Sources/Server.swift

@@ -79,14 +79,14 @@ public class Server {
       while(running) {
         let handler = Handler(underlyingHandler:cgrpc_handler_create_with_server(self.underlyingServer))
         let call_error = handler.requestCall(tag:101)
-        if (call_error != GRPC_CALL_OK) {
+        if (call_error != .ok) {
           // not good, let's break
           break
         }
         // blocks
         let event = self.completionQueue.waitForCompletion(timeout:600)
-        if (event.type == GRPC_OP_COMPLETE) {
-          if cgrpc_event_tag(event) == 101 {
+        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)
@@ -96,12 +96,12 @@ public class Server {
               }
               handlerFunction(handler)
             }
-          } else if cgrpc_event_tag(event) == 0 {
+          } else if event.tag == 0 {
             running = false // exit the loop
           }
-        } else if (event.type == GRPC_QUEUE_TIMEOUT) {
+        } else if (event.type == .queueTimeout) {
           // everything is fine
-        } else if (event.type == GRPC_QUEUE_SHUTDOWN) {
+        } else if (event.type == .queueShutdown) {
           running = false
         }
       }
@@ -122,21 +122,21 @@ public class Server {
   /// 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: Double) -> (grpc_call_error, grpc_completion_type, Handler?) {
+  private func getNextRequest(timeout: Double) -> (CallError, CompletionType, Handler?) {
     let handler = Handler(underlyingHandler:cgrpc_handler_create_with_server(underlyingServer))
     let call_error = handler.requestCall(tag:101)
-    if (call_error != GRPC_CALL_OK) {
-      return (call_error, GRPC_OP_COMPLETE, nil)
+    if (call_error != .ok) {
+      return (call_error, .complete, nil)
     } else {
       let event = self.completionQueue.waitForCompletion(timeout:timeout)
-      if (event.type == GRPC_OP_COMPLETE) {
+      if (event.type == .complete) {
         handler.completionQueue.run() {
           self.handlers.remove(handler)
         }
         self.handlers.add(handler)
-        return (GRPC_CALL_OK, GRPC_OP_COMPLETE, handler)
+        return (.ok, .complete, handler)
       } else {
-        return (GRPC_CALL_OK, event.type, nil)
+        return (.ok, event.type, nil)
       }
     }
   }