Bladeren bron

Extract more common code into `ServiceServer` protocols and classes.

Daniel Alm 7 jaren geleden
bovenliggende
commit
929fea4097

+ 36 - 71
Examples/Echo/Generated/echo.grpc.swift

@@ -241,84 +241,49 @@ class Echo_EchoUpdateSessionTestStub: ServerSessionBidirectionalStreamingTestStu
 
 
 /// Main server for generated service
-internal final class Echo_EchoServer {
-  private var address: String
-  private var server: Server
-  private var provider: Echo_EchoProvider?
-
-  /// Create a server that accepts insecure connections.
-  internal init(address:String,
-              provider:Echo_EchoProvider) {
-    gRPC.initialize()
-    self.address = address
+internal final class Echo_EchoServer: ServiceServer {
+  private var provider: Echo_EchoProvider
+
+  internal init(address: String, provider: Echo_EchoProvider) {
     self.provider = provider
-    self.server = Server(address:address)
+    super.init(address: address)
   }
 
-  /// Create a server that accepts secure connections.
-  internal init?(address:String,
-               certificateURL:URL,
-               keyURL:URL,
-               provider:Echo_EchoProvider) {
-    gRPC.initialize()
-    self.address = address
+  internal init?(address: String, certificateURL: URL, keyURL: URL, provider: Echo_EchoProvider) {
     self.provider = provider
-    guard
-      let certificate = try? String(contentsOf: certificateURL, encoding: .utf8),
-      let key = try? String(contentsOf: keyURL, encoding: .utf8)
-      else {
-        return nil
-    }
-    self.server = Server(address:address, key:key, certs:certificate)
+    super.init(address: address, certificateURL: certificateURL, keyURL: keyURL)
   }
 
   /// Start the server.
-  internal func start(queue:DispatchQueue = DispatchQueue.global()) {
-    guard let provider = self.provider else {
-      fatalError() // the server requires a provider
-    }
-    server.run {(handler) in
-      let unwrappedHost = handler.host ?? "(nil)"
-      let unwrappedMethod = handler.method ?? "(nil)"
-      let unwrappedCaller = handler.caller ?? "(nil)"
-      print("Server received request to " + unwrappedHost
-        + " calling " + unwrappedMethod
-        + " from " + unwrappedCaller
-        + " with " + handler.requestMetadata.description)
-
-      do {
-        switch unwrappedMethod {
-        case "/echo.Echo/Get":
-          try Echo_EchoGetSessionImpl(
-            handler: handler,
-            providerBlock: { try provider.get(request: $0, session: $1 as! Echo_EchoGetSessionImpl) })
-              .run(queue:queue)
-        case "/echo.Echo/Expand":
-          try Echo_EchoExpandSessionImpl(
-            handler: handler,
-            providerBlock: { try provider.expand(request: $0, session: $1 as! Echo_EchoExpandSessionImpl) })
-              .run(queue:queue)
-        case "/echo.Echo/Collect":
-          try Echo_EchoCollectSessionImpl(
-            handler: handler,
-            providerBlock: { try provider.collect(session: $0 as! Echo_EchoCollectSessionImpl) })
-              .run(queue:queue)
-        case "/echo.Echo/Update":
-          try Echo_EchoUpdateSessionImpl(
-            handler: handler,
-            providerBlock: { try provider.update(session: $0 as! Echo_EchoUpdateSessionImpl) })
-              .run(queue:queue)
-        default:
-          // handle unknown requests
-          try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
-            try handler.sendResponse(statusCode:.unimplemented,
-                                     statusMessage:"unknown method " + unwrappedMethod,
-                                     trailingMetadata:Metadata())
-          }
-        }
-      } catch (let error) {
-        print("Server error: \(error)")
-      }
+  internal override func handleMethod(_ method: String, handler: Handler, queue: DispatchQueue) throws -> Bool {
+    let provider = self.provider
+    switch method {
+    case "/echo.Echo/Get":
+      try Echo_EchoGetSessionImpl(
+        handler: handler,
+        providerBlock: { try provider.get(request: $0, session: $1 as! Echo_EchoGetSessionImpl) })
+          .run(queue: queue)
+      return true
+    case "/echo.Echo/Expand":
+      try Echo_EchoExpandSessionImpl(
+        handler: handler,
+        providerBlock: { try provider.expand(request: $0, session: $1 as! Echo_EchoExpandSessionImpl) })
+          .run(queue: queue)
+      return true
+    case "/echo.Echo/Collect":
+      try Echo_EchoCollectSessionImpl(
+        handler: handler,
+        providerBlock: { try provider.collect(session: $0 as! Echo_EchoCollectSessionImpl) })
+          .run(queue: queue)
+      return true
+    case "/echo.Echo/Update":
+      try Echo_EchoUpdateSessionImpl(
+        handler: handler,
+        providerBlock: { try provider.update(session: $0 as! Echo_EchoUpdateSessionImpl) })
+          .run(queue: queue)
+      return true
+    default:
+      return false
     }
   }
 }

+ 26 - 64
Plugin/Templates/server.swift

@@ -33,78 +33,40 @@
 //-{% endfor %}
 
 /// Main server for generated service
-{{ access }} final class {{ .|server:file,service }} {
-  private var address: String
-  private var server: Server
-  private var provider: {{ .|provider:file,service }}?
+{{ access }} final class {{ .|server:file,service }}: ServiceServer {
+  private var provider: {{ .|provider:file,service }}
 
-  /// Create a server that accepts insecure connections.
-  {{ access }} init(address:String,
-              provider:{{ .|provider:file,service }}) {
-    gRPC.initialize()
-    self.address = address
+  {{ access }} init(address: String, provider: {{ .|provider:file,service }}) {
     self.provider = provider
-    self.server = Server(address:address)
+    super.init(address: address)
   }
 
-  /// Create a server that accepts secure connections.
-  {{ access }} init?(address:String,
-               certificateURL:URL,
-               keyURL:URL,
-               provider:{{ .|provider:file,service }}) {
-    gRPC.initialize()
-    self.address = address
+  {{ access }} init?(address: String, certificateURL: URL, keyURL: URL, provider: {{ .|provider:file,service }}) {
     self.provider = provider
-    guard
-      let certificate = try? String(contentsOf: certificateURL, encoding: .utf8),
-      let key = try? String(contentsOf: keyURL, encoding: .utf8)
-      else {
-        return nil
-    }
-    self.server = Server(address:address, key:key, certs:certificate)
+    super.init(address: address, certificateURL: certificateURL, keyURL: keyURL)
   }
 
   /// Start the server.
-  {{ access }} func start(queue:DispatchQueue = DispatchQueue.global()) {
-    guard let provider = self.provider else {
-      fatalError() // the server requires a provider
-    }
-    server.run {(handler) in
-      let unwrappedHost = handler.host ?? "(nil)"
-      let unwrappedMethod = handler.method ?? "(nil)"
-      let unwrappedCaller = handler.caller ?? "(nil)"
-      print("Server received request to " + unwrappedHost
-        + " calling " + unwrappedMethod
-        + " from " + unwrappedCaller
-        + " with " + handler.requestMetadata.description)
-
-      do {
-        switch unwrappedMethod {
-        //-{% for method in service.methods %}
-        case "{{ .|path:file,service,method }}":
-          //-{% if method|methodIsUnary or method|methodIsServerStreaming %}
-          try {{ .|session:file,service,method }}Impl(
-            handler: handler,
-            providerBlock: { try provider.{{ method|methodDescriptorName|lowercase }}(request: $0, session: $1 as! {{ .|session:file,service,method }}Impl) })
-              .run(queue:queue)
-          //-{% else %}
-          try {{ .|session:file,service,method }}Impl(
-            handler: handler,
-            providerBlock: { try provider.{{ method|methodDescriptorName|lowercase }}(session: $0 as! {{ .|session:file,service,method }}Impl) })
-              .run(queue:queue)
-          //-{% endif %}
-        //-{% endfor %}
-        default:
-          // handle unknown requests
-          try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
-            try handler.sendResponse(statusCode:.unimplemented,
-                                     statusMessage:"unknown method " + unwrappedMethod,
-                                     trailingMetadata:Metadata())
-          }
-        }
-      } catch (let error) {
-        print("Server error: \(error)")
-      }
+  {{ access }} override func handleMethod(_ method: String, handler: Handler, queue: DispatchQueue) throws -> Bool {
+    let provider = self.provider
+    switch method {
+    //-{% for method in service.methods %}
+    case "{{ .|path:file,service,method }}":
+      //-{% if method|methodIsUnary or method|methodIsServerStreaming %}
+      try {{ .|session:file,service,method }}Impl(
+        handler: handler,
+        providerBlock: { try provider.{{ method|methodDescriptorName|lowercase }}(request: $0, session: $1 as! {{ .|session:file,service,method }}Impl) })
+          .run(queue: queue)
+      //-{% else %}
+      try {{ .|session:file,service,method }}Impl(
+        handler: handler,
+        providerBlock: { try provider.{{ method|methodDescriptorName|lowercase }}(session: $0 as! {{ .|session:file,service,method }}Impl) })
+          .run(queue: queue)
+      //-{% endif %}
+      return true
+    //-{% endfor %}
+    default:
+      return false
     }
   }
 }

+ 4 - 4
Sources/gRPC/GenCodeSupport/ServiceClient.swift

@@ -34,16 +34,16 @@ public protocol ServiceClient {
 }
 
 open class ServiceClientBase: ServiceClient {
-  open private(set) var channel: Channel
+  public let channel: Channel
   
-  open var metadata : Metadata
+  public var metadata: Metadata
   
-  open var host : String {
+  public var host: String {
     get { return self.channel.host }
     set { self.channel.host = newValue }
   }
   
-  open var timeout : TimeInterval {
+  public var timeout: TimeInterval {
     get { return self.channel.timeout }
     set { self.channel.timeout = newValue }
   }

+ 76 - 0
Sources/gRPC/GenCodeSupport/ServiceServer.swift

@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018, 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.
+ */
+
+import Dispatch
+import Foundation
+import SwiftProtobuf
+
+open class ServiceServer {
+  public let address: String
+  public let server: Server
+  
+  /// Create a server that accepts insecure connections.
+  public init(address: String) {
+    gRPC.initialize()
+    self.address = address
+    self.server = Server(address: address)
+  }
+  
+  /// Create a server that accepts secure connections.
+  public init?(address:String, certificateURL: URL, keyURL: URL) {
+    gRPC.initialize()
+    self.address = address
+    guard let certificate = try? String(contentsOf: certificateURL, encoding: .utf8),
+      let key = try? String(contentsOf: keyURL, encoding: .utf8)
+      else { return nil }
+    self.server = Server(address: address, key: key, certs: certificate)
+  }
+  
+  /// Handle the given method. Needs to be overridden by actual implementations.
+  /// Returns whether the method was actually handled.
+  open func handleMethod(_ method: String, handler: Handler, queue: DispatchQueue) throws -> Bool { fatalError("needs to be overridden") }
+  
+  /// Start the server.
+  public func start(queue: DispatchQueue = DispatchQueue.global()) {
+    server.run { [weak self] handler in
+      guard let strongSelf = self else {
+        print("ERROR: ServiceServer has been asked to handle a request even though it has already been deallocated")
+        return
+      }
+      
+      let unwrappedHost = handler.host ?? "(nil)"
+      let unwrappedMethod = handler.method ?? "(nil)"
+      let unwrappedCaller = handler.caller ?? "(nil)"
+      print("Server received request to " + unwrappedHost
+        + " calling " + unwrappedMethod
+        + " from " + unwrappedCaller
+        + " with " + handler.requestMetadata.description)
+      
+      do {
+        if try !strongSelf.handleMethod(unwrappedMethod, handler: handler, queue: queue) {
+          // handle unknown requests
+          try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
+            try handler.sendResponse(statusCode: .unimplemented,
+                                     statusMessage: "unknown method " + unwrappedMethod,
+                                     trailingMetadata: Metadata())
+          }
+        }
+      } catch (let error) {
+        print("Server error: \(error)")
+      }
+    }
+  }
+}