Browse Source

Refactoring FileDescriptorSet usage out of internal interfaces

Tim Burks 9 years ago
parent
commit
3f9c38dc1a

+ 19 - 0
Examples/Echo/Swift/Echo.xcodeproj/project.pbxproj

@@ -7,6 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		D30DACF01DB6FC2D00886B20 /* EchoService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D30DACEF1DB6FC2D00886B20 /* EchoService.swift */; };
 		D324A6021D81CF8F00421B59 /* EchoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D324A6011D81CF8F00421B59 /* EchoServer.swift */; };
 		D35C9FAC1D74B079000443CD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D35C9FAB1D74B079000443CD /* AppDelegate.swift */; };
 		D35C9FAE1D74B079000443CD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D35C9FAD1D74B079000443CD /* Assets.xcassets */; };
@@ -20,6 +21,13 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+		D30DACF41DB6FC2E00886B20 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = D3D2EA3F1D75FB60002EF89C /* QuickProto.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = D3275BF41D8B22DC00CDE67D;
+			remoteInfo = QuickProtoApp;
+		};
 		D3BFE28F1D87A45D00A648D8 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = D3D2EA3F1D75FB60002EF89C /* QuickProto.xcodeproj */;
@@ -65,6 +73,7 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		D30DACEF1DB6FC2D00886B20 /* EchoService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EchoService.swift; sourceTree = "<group>"; };
 		D324A6011D81CF8F00421B59 /* EchoServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EchoServer.swift; sourceTree = "<group>"; };
 		D35C9FA81D74B079000443CD /* Echo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Echo.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		D35C9FAB1D74B079000443CD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -122,6 +131,7 @@
 				D35C9FB21D74B079000443CD /* Info.plist */,
 				D35C9FC71D74B0C1000443CD /* EchoViewController.swift */,
 				D324A6011D81CF8F00421B59 /* EchoServer.swift */,
+				D30DACEF1DB6FC2D00886B20 /* EchoService.swift */,
 			);
 			path = Echo;
 			sourceTree = "<group>";
@@ -140,6 +150,7 @@
 				D3D2EA451D75FB60002EF89C /* QuickProto.framework */,
 				D3BFE2901D87A45D00A648D8 /* QuickProtoTests.xctest */,
 				D3BFE2921D87A45D00A648D8 /* QuickProtoGen.app */,
+				D30DACF51DB6FC2E00886B20 /* QuickProtoApp.app */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -212,6 +223,13 @@
 /* End PBXProject section */
 
 /* Begin PBXReferenceProxy section */
+		D30DACF51DB6FC2E00886B20 /* QuickProtoApp.app */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.application;
+			path = QuickProtoApp.app;
+			remoteRef = D30DACF41DB6FC2E00886B20 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
 		D3BFE2901D87A45D00A648D8 /* QuickProtoTests.xctest */ = {
 			isa = PBXReferenceProxy;
 			fileType = wrapper.cfbundle;
@@ -262,6 +280,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				D30DACF01DB6FC2D00886B20 /* EchoService.swift in Sources */,
 				D324A6021D81CF8F00421B59 /* EchoServer.swift in Sources */,
 				D35C9FC81D74B0C1000443CD /* EchoViewController.swift in Sources */,
 				D35C9FAC1D74B079000443CD /* AppDelegate.swift in Sources */,

+ 7 - 13
Examples/Echo/Swift/Echo/EchoServer.swift

@@ -36,23 +36,21 @@ import QuickProto
 
 class EchoGetHandler : HandlerHelper {
   var requestHandler : Handler
-  var fileDescriptorSet: FileDescriptorSet
   var service : EchoGetService
 
   init(requestHandler:Handler,
-       fileDescriptorSet: FileDescriptorSet,
        service: EchoGetService) {
     self.requestHandler = requestHandler
-    self.fileDescriptorSet = fileDescriptorSet
     self.service = service
   }
 
   // return an empty message of the destination type
   func replyMessage() -> Message {
+    let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out")!
     return fileDescriptorSet.makeMessage("EchoResponse")!
   }
 
-  // send a message 
+  // send a message
   func sendMessage(message:Message) -> Void {
     try! requestHandler.sendResponse(message:message.data()) {}
   }
@@ -61,7 +59,8 @@ class EchoGetHandler : HandlerHelper {
     do {
       try requestHandler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
         if let requestData = requestData,
-          let requestMessage = self.fileDescriptorSet.readMessage("EchoRequest", data:requestData) {
+          let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out"),
+          let requestMessage = fileDescriptorSet.readMessage("EchoRequest", data:requestData) {
           if let replyMessage = self.service.handle(handler:self, request:requestMessage) { // calling stub
             try self.requestHandler.sendResponse(message:replyMessage.data(),
                                                  statusCode: 0,
@@ -78,18 +77,16 @@ class EchoGetHandler : HandlerHelper {
 
 class EchoUpdateHandler : HandlerHelper {
   var requestHandler : Handler
-  var fileDescriptorSet: FileDescriptorSet
   var service : EchoUpdateService
 
   init(requestHandler:Handler,
-       fileDescriptorSet: FileDescriptorSet,
        service: EchoUpdateService) {
     self.requestHandler = requestHandler
-    self.fileDescriptorSet = fileDescriptorSet
     self.service = service
   }
 
   func replyMessage() -> Message {
+    let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out")!
     return fileDescriptorSet.makeMessage("EchoResponse")!
   }
 
@@ -101,7 +98,8 @@ class EchoUpdateHandler : HandlerHelper {
     do {
       try requestHandler.receiveMessage() {(requestData) in
         if let requestData = requestData {
-          if let requestMessage = self.fileDescriptorSet.readMessage("EchoRequest", data:requestData) {
+          if let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out"),
+            let requestMessage = fileDescriptorSet.readMessage("EchoRequest", data:requestData) {
             self.wait()
             self.service.handle(handler:self, request:requestMessage)
           }
@@ -134,7 +132,6 @@ class EchoUpdateHandler : HandlerHelper {
 class EchoServer {
   private var address: String
   private var server: Server
-  private var fileDescriptorSet : FileDescriptorSet
   private var handlers: Set<NSObject> = []
 
   init(address:String, secure:Bool) {
@@ -149,7 +146,6 @@ class EchoServer {
     } else {
       self.server = gRPC.Server(address:address)
     }
-    fileDescriptorSet = FileDescriptorSet(filename:"echo.out")
   }
 
   func start() {
@@ -163,14 +159,12 @@ class EchoServer {
 
       if (requestHandler.method == "/echo.Echo/Get") {
         requestHandler.helper = EchoGetHandler(requestHandler:requestHandler,
-                                               fileDescriptorSet:self.fileDescriptorSet,
                                                service:EchoGetService())
         requestHandler.helper.run()
       }
 
       if (requestHandler.method == "/echo.Echo/Update") {
         requestHandler.helper = EchoUpdateHandler(requestHandler:requestHandler,
-                                                  fileDescriptorSet:self.fileDescriptorSet,
                                                   service:EchoUpdateService())
         requestHandler.helper.run()
       }

+ 94 - 0
Examples/Echo/Swift/Echo/EchoService.swift

@@ -0,0 +1,94 @@
+//
+//  EchoService.swift
+//  Echo
+//
+//  Created by Tim Burks on 10/18/16.
+//  Copyright © 2016 Google. All rights reserved.
+//
+
+import Foundation
+import gRPC
+import QuickProto
+
+// all code that follows is to-be-generated
+
+public class EchoGetCall {
+  var call : Call
+
+  init(_ call: Call) {
+    self.call = call
+  }
+
+  func perform(request: Message, callback:@escaping (CallResult, Message?) -> Void) -> Void {
+    let requestMessageData = request.data()
+    let requestMetadata = Metadata()
+    try! call.perform(message: requestMessageData,
+                      metadata: requestMetadata)
+    {(callResult) in
+      print("Client received status \(callResult.statusCode): \(callResult.statusMessage!)")
+
+      if let messageData = callResult.resultData,
+        let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out"),
+        let responseMessage = fileDescriptorSet.readMessage("EchoResponse",
+                                                            data:messageData) {
+
+        callback(callResult, responseMessage)
+      } else {
+        callback(callResult, nil)
+      }
+    }
+  }
+}
+
+public class EchoUpdateCall {
+  var call : Call
+
+  init(_ call: Call) {
+    self.call = call
+  }
+
+  func start(metadata:Metadata) throws {
+    try self.call.start(metadata: metadata)
+  }
+
+  func receiveMessage(callback:@escaping (Message?) throws -> Void) throws {
+    try call.receiveMessage() {(data) in
+      guard
+        let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out"),
+        let responseMessage = fileDescriptorSet.readMessage("EchoResponse", data:data)
+        else {
+          return
+      }
+      try callback(responseMessage)
+    }
+  }
+
+  func sendMessage(message:Message) {
+    let messageData = message.data()
+    _ = call.sendMessage(data:messageData)
+  }
+
+  func close(completion:@escaping (() -> Void)) throws {
+    try call.close(completion:completion)
+  }
+}
+
+public class EchoService {
+  public var channel: Channel
+
+  public init(address: String) {
+    channel = Channel(address:address)
+  }
+
+  public init(address: String, certificates: String?, host: String?) {
+    channel = Channel(address:address, certificates:certificates, host:host)
+  }
+
+  func get() -> EchoGetCall {
+    return EchoGetCall(channel.makeCall("/echo.Echo/Get"))
+  }
+
+  func update() -> EchoUpdateCall {
+    return EchoUpdateCall(channel.makeCall("/echo.Echo/Update"))
+  }
+}

+ 8 - 92
Examples/Echo/Swift/Echo/EchoViewController.swift

@@ -41,8 +41,6 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
   @IBOutlet weak var streamingButton: NSButton!
   @IBOutlet weak var TLSButton: NSButton!
 
-  private var fileDescriptorSet : FileDescriptorSet
-
   private var service : EchoService?
 
   private var channel: Channel?
@@ -51,7 +49,6 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
   private var nowStreaming = false
 
   required init?(coder:NSCoder) {
-    fileDescriptorSet = FileDescriptorSet(filename: "echo.out")
     super.init(coder:coder)
   }
 
@@ -104,7 +101,6 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     }
     if let service = service {
       service.channel.host = host
-      service.fileDescriptorSet = fileDescriptorSet
     }
   }
 
@@ -114,7 +110,8 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     let host = "example.com"
     if (self.streamingButton.intValue == 0) {
       // NONSTREAMING
-      if let requestMessage = self.fileDescriptorSet.makeMessage("EchoRequest") {
+      if let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out"),
+        let requestMessage = fileDescriptorSet.makeMessage("EchoRequest") {
         requestMessage.addField("text", value:self.messageField.stringValue)
         prepareService(address:address, host:host)
         if let service = service {
@@ -152,10 +149,12 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
   }
 
   func sendMessage() {
-    let requestMessage = self.fileDescriptorSet.makeMessage("EchoRequest")!
-    requestMessage.addField("text", value:self.messageField.stringValue)
-    if let updateCall = updateCall {
-      _ = updateCall.sendMessage(message:requestMessage)
+    if let fileDescriptorSet = FileDescriptorSet.from(filename:"echo.out") {
+      let requestMessage = fileDescriptorSet.makeMessage("EchoRequest")!
+      requestMessage.addField("text", value:self.messageField.stringValue)
+      if let updateCall = updateCall {
+        _ = updateCall.sendMessage(message:requestMessage)
+      }
     }
   }
 
@@ -185,88 +184,5 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
   }
 }
 
-// all code that follows is to-be-generated
-
-class EchoGetCall {
-  var call : Call
-  var fileDescriptorSet: FileDescriptorSet
-
-  init(_ call: Call, fileDescriptorSet: FileDescriptorSet) {
-    self.call = call
-    self.fileDescriptorSet = fileDescriptorSet
-  }
-
-  func perform(request: Message, callback:@escaping (CallResult, Message?) -> Void) -> Void {
-    let requestMessageData = request.data()
-    let requestMetadata = Metadata()
-    try! call.perform(message: requestMessageData,
-                      metadata: requestMetadata)
-    {(callResult) in
-      print("Client received status \(callResult.statusCode): \(callResult.statusMessage!)")
-
-      if let messageData = callResult.resultData,
-        let responseMessage = self.fileDescriptorSet.readMessage("EchoResponse",
-                                                                 data:messageData) {
-
-        callback(callResult, responseMessage)
-      } else {
-        callback(callResult, nil)
-      }
-    }
-  }
-}
-
-class EchoUpdateCall {
-  var call : Call
-  var fileDescriptorSet: FileDescriptorSet
 
-  init(_ call: Call, fileDescriptorSet: FileDescriptorSet) {
-    self.call = call
-    self.fileDescriptorSet = fileDescriptorSet
-  }
-
-  func start(metadata:Metadata) throws {
-    try self.call.start(metadata: metadata)
-  }
-
-  func receiveMessage(callback:@escaping (Message?) throws -> Void) throws {
-    try call.receiveMessage() {(data) in
-      guard let responseMessage = self.fileDescriptorSet.readMessage("EchoResponse", data:data)
-        else {
-          return // this stops receiving
-      }
-      try callback(responseMessage)
-    }
-  }
-
-  func sendMessage(message:Message) {
-    let messageData = message.data()
-    _ = call.sendMessage(data:messageData)
-  }
-
-  func close(completion:@escaping (() -> Void)) throws {
-    try call.close(completion:completion)
-  }
-}
-
-class EchoService {
-  public var channel: Channel
-  public var fileDescriptorSet: FileDescriptorSet!
-
-  public init(address: String) {
-    channel = Channel(address:address)
-  }
-
-  public init(address: String, certificates: String?, host: String?) {
-    channel = Channel(address:address, certificates:certificates, host:host)
-  }
-
-  func get() -> EchoGetCall {
-    return EchoGetCall(channel.makeCall("/echo.Echo/Get"), fileDescriptorSet:fileDescriptorSet)
-  }
-
-  func update() -> EchoUpdateCall {
-    return EchoUpdateCall(channel.makeCall("/echo.Echo/Update"), fileDescriptorSet:fileDescriptorSet)
-  }
-}
 

+ 12 - 1
Packages/QuickProto/Sources/FileDescriptorSet.swift

@@ -44,7 +44,6 @@ public class FileDescriptorSet {
     let baseFileDescriptorSet = FileDescriptorSet()
     if let descriptorMessage = baseFileDescriptorSet.readMessage("FileDescriptorSet",
                                                                  data:data) {
-      descriptorMessage.display()
       descriptorMessage.forEachField("file") { (field) in
         let fileDescriptor = FileDescriptor(message: field.message())
         fileDescriptors.append(fileDescriptor)
@@ -52,6 +51,18 @@ public class FileDescriptorSet {
     }
   }
 
+  private static var cache : [String:FileDescriptorSet] = [:]
+
+  public class func from(filename:String) -> FileDescriptorSet? {
+    if let fileDescriptorSet = cache[filename] {
+      return fileDescriptorSet
+    } else {
+      let fileDescriptorSet = FileDescriptorSet(filename:filename)
+      cache[filename] = fileDescriptorSet
+      return fileDescriptorSet
+    }
+  }
+
 #if !SWIFT_PACKAGE
   convenience public init(filename:String) {
     let path = Bundle.main.resourcePath!.appending("/").appending(filename)