瀏覽代碼

Improve StatusCode usage and handling of unknown messages in generated servers.

Tim Burks 7 年之前
父節點
當前提交
55077aca5c

+ 6 - 1
Examples/Echo/Generated/echo.grpc.swift

@@ -635,7 +635,12 @@ internal class Echo_EchoServer {
         case "/echo.Echo/Update":
           try Echo_EchoUpdateSession(handler:handler, provider:provider).run(queue:queue)
         default:
-          break // handle unknown requests
+          // handle unknown requests
+          try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
+            try handler.sendResponse(statusCode:12,
+                                     statusMessage:"unimplemented " + handler.method,
+                                     trailingMetadata:Metadata())
+          }
         }
       } catch (let error) {
         print("Server error: \(error)")

文件差異過大導致無法顯示
+ 2 - 0
Plugin/Sources/protoc-gen-swiftgrpc/templates.swift


+ 7 - 2
Plugin/Templates/server.swift

@@ -28,7 +28,7 @@
   fileprivate var handler : gRPC.Handler
   {{ access }} var requestMetadata : Metadata { return handler.requestMetadata }
 
-  {{ access }} var statusCode : Int = 0
+  {{ access }} var statusCode : StatusCode = .ok
   {{ access }} var statusMessage : String = "OK"
   {{ access }} var initialMetadata : Metadata = Metadata()
   {{ access }} var trailingMetadata : Metadata = Metadata()
@@ -103,7 +103,12 @@
           try {{ .|session:file,service,method }}(handler:handler, provider:provider).run(queue:queue)
         //-{% endfor %}
         default:
-          break // handle unknown requests
+          // handle unknown requests
+          try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
+            try handler.sendResponse(statusCode:.unimplemented,
+                                     statusMessage:"unknown method " + handler.method,
+                                     trailingMetadata:Metadata())
+          }
         }
       } catch (let error) {
         print("Server error: \(error)")

+ 9 - 5
Sources/gRPC/Call.swift

@@ -86,7 +86,7 @@ public enum CallError : Error {
 }
 
 public struct CallResult : CustomStringConvertible {
-  public var statusCode : Int
+  public var statusCode : StatusCode
   public var statusMessage : String?
   public var resultData : Data?
   public var initialMetadata : Metadata?
@@ -94,17 +94,21 @@ public struct CallResult : CustomStringConvertible {
 
   fileprivate init(_ op : OperationGroup) {
     if (op.success) {
-      if let statusCode = op.receivedStatusCode() {
-        self.statusCode = statusCode
+      if let statusCodeRawValue = op.receivedStatusCode() {
+	if let statusCode = StatusCode(rawValue:statusCodeRawValue) {
+          self.statusCode = statusCode
+	} else {
+	  self.statusCode = .unknown
+	}
       } else {
-        self.statusCode = 0
+	self.statusCode = .ok
       }
       self.statusMessage = op.receivedStatusMessage()
       self.resultData = op.receivedMessage()?.data()
       self.initialMetadata = op.receivedInitialMetadata()
       self.trailingMetadata = op.receivedTrailingMetadata()
     } else {
-      self.statusCode = 0
+      self.statusCode = .ok
       self.statusMessage = nil
       self.resultData = nil
       self.initialMetadata = nil

+ 42 - 19
Sources/gRPC/Handler.swift

@@ -22,20 +22,20 @@ import Foundation // for String.Encoding
 public class Handler {
   /// Pointer to underlying C representation
   private var underlyingHandler: UnsafeMutableRawPointer
-
+  
   /// Completion queue for handler response operations
   internal var completionQueue: CompletionQueue
-
+  
   /// Metadata received with the request
   public var requestMetadata: Metadata
-
+  
   /// A Call object that can be used to respond to the request
   internal lazy var call: Call = {
     return Call(underlyingCall: cgrpc_handler_get_call(self.underlyingHandler),
                 owned: false,
                 completionQueue: self.completionQueue)
   }()
-
+  
   /// The host name sent with the request
   public lazy var host: String = {
     if let string = cgrpc_handler_copy_host(self.underlyingHandler) {
@@ -47,7 +47,7 @@ public class Handler {
       return ""
     }
   }()
-
+  
   /// The method name sent with the request
   public lazy var method: String = {
     if let string = cgrpc_handler_copy_method(self.underlyingHandler) {
@@ -59,13 +59,13 @@ public class Handler {
       return ""
     }
   }()
-
+  
   /// The caller address associated with the request
   public lazy var caller: String = {
     return String(cString:cgrpc_handler_call_peer(self.underlyingHandler),
                   encoding:.utf8)!;
   }()
-
+  
   /// Initializes a Handler
   ///
   /// - Parameter underlyingServer: the underlying C representation of the associated server
@@ -76,11 +76,11 @@ public class Handler {
       underlyingCompletionQueue:cgrpc_handler_get_completion_queue(underlyingHandler))
     completionQueue.name = "Handler"
   }
-
+  
   deinit {
     cgrpc_handler_destroy(self.underlyingHandler)
   }
-
+  
   /// Requests a call for the handler
   ///
   /// Fills the handler properties with information about the received request
@@ -91,7 +91,7 @@ public class Handler {
       throw CallError.callError(grpcCallError: error)
     }
   }
-
+  
   /// Receive the message sent with a call
   ///
   public func receiveMessage(initialMetadata: Metadata,
@@ -110,13 +110,15 @@ public class Handler {
     }
     try call.perform(operations)
   }
-
+  
   /// Sends the response to a request
   ///
   /// - Parameter message: the message to send
+  /// - Parameter statusCode: status code to send
+  /// - Parameter statusMessage: status message to send
   /// - Parameter trailingMetadata: trailing metadata to send
   public func sendResponse(message: Data,
-                           statusCode: Int,
+                           statusCode: StatusCode,
                            statusMessage: String,
                            trailingMetadata: Metadata) throws -> Void {
     let messageBuffer = ByteBuffer(data:message)
@@ -133,12 +135,33 @@ public class Handler {
     }
     try call.perform(operations)
   }
-
+  
+  /// Sends the response to a request
+  ///
+  /// - Parameter statusCode: status code to send
+  /// - Parameter statusMessage: status message to send
+  /// - Parameter trailingMetadata: trailing metadata to send
+  public func sendResponse(statusCode: StatusCode,
+                           statusMessage: String,
+                           trailingMetadata: Metadata) throws -> Void {
+    let operations = OperationGroup(
+      call:call,
+      operations:[
+        .receiveCloseOnServer,
+        .sendStatusFromServer(statusCode, statusMessage, trailingMetadata)])
+    {(operationGroup) in
+      if operationGroup.success {
+        self.shutdown()
+      }
+    }
+    try call.perform(operations)
+  }
+  
   /// Shuts down the handler's completion queue
   public func shutdown() {
     completionQueue.shutdown()
   }
-
+  
   /// Send initial metadata in response to a connection
   ///
   /// - Parameter initialMetadata: initial metadata to send
@@ -156,7 +179,7 @@ public class Handler {
     }
     try call.perform(operations)
   }
-
+  
   /// Receive the message sent with a call
   ///
   /// - Parameter completion: a completion handler to call after the message has been received
@@ -176,7 +199,7 @@ public class Handler {
     }
     try call.perform(operations)
   }
-
+  
   /// Sends the response to a request
   ///
   /// - Parameter message: the message to send
@@ -192,7 +215,7 @@ public class Handler {
     }
     try call.perform(operations)
   }
-
+  
   /// Recognize when the client has closed a request
   ///
   /// - Parameter completion: a completion handler to call after request has been closed
@@ -206,14 +229,14 @@ public class Handler {
     }
     try call.perform(operations)
   }
-
+  
   /// Send final status to the client
   ///
   /// - 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,
+  public func sendStatus(statusCode: StatusCode,
                          statusMessage: String,
                          trailingMetadata: Metadata,
                          completion:@escaping (() -> Void)) throws -> Void {

+ 1 - 1
Sources/gRPC/Operation.swift

@@ -21,7 +21,7 @@ enum Operation {
   case sendInitialMetadata(Metadata)
   case sendMessage(ByteBuffer)
   case sendCloseFromClient
-  case sendStatusFromServer(Int, String, Metadata)
+  case sendStatusFromServer(StatusCode, String, Metadata)
   case receiveInitialMetadata
   case receiveMessage
   case receiveStatusOnClient

+ 1 - 1
Sources/gRPC/OperationGroup.swift

@@ -63,7 +63,7 @@ internal class OperationGroup {
       underlyingObserver = cgrpc_observer_create_send_close_from_client()!
     case .sendStatusFromServer(let statusCode, let statusMessage, let metadata):
       underlyingObserver = cgrpc_observer_create_send_status_from_server(metadata.underlyingArray)!
-      cgrpc_observer_send_status_from_server_set_status(underlyingObserver, Int32(statusCode))
+      cgrpc_observer_send_status_from_server_set_status(underlyingObserver, Int32(statusCode.rawValue))
       cgrpc_observer_send_status_from_server_set_status_details(underlyingObserver, statusMessage)
     case .receiveInitialMetadata:
       underlyingObserver = cgrpc_observer_create_recv_initial_metadata()!

+ 1 - 1
Sources/gRPC/gRPC.swift

@@ -43,7 +43,7 @@ public func gStandsFor() -> String {
 }
 
 /// Status codes for gRPC operations (replicated from status_code_enum.h)
-enum StatusCode: Int {
+public enum StatusCode: Int {
   /// Not an error; returned on success.
   case ok = 0
 

+ 1 - 1
Tests/gRPCTests/GRPCTests.swift

@@ -52,7 +52,7 @@
    "2": "two"]
  let steps = 10
  let hello = "/hello"
- let statusCode = 0
+ let statusCode = StatusCode.ok
  let statusMessage = "OK"
 
  func runTest(useSSL: Bool) {

部分文件因文件數量過多而無法顯示