Browse Source

a few api simplifications and an improvement to the Echo sample

changes to the address field now restart any existing streaming calls
Tim Burks 9 years ago
parent
commit
54815990be

+ 12 - 10
Examples/Echo/Swift/Echo/AppDelegate.swift

@@ -56,6 +56,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
         + " calling " + requestHandler.method()
         + " from " + requestHandler.caller())
 
+      // NONSTREAMING
       if (requestHandler.method() == "/echo.Echo/Get") {
         requestHandler.receiveMessage(initialMetadata:Metadata())
         {(requestBuffer) in
@@ -65,8 +66,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
                                           proto:requestBuffer.data()) {
             requestMessage.forOneField(name:"text") {(field) in
               let replyMessage = fileDescriptorSet.createMessage(name:"EchoResponse")!
-              let text = "Swift nonstreaming echo " + field.string()
-              replyMessage.addField(name:"text", value:text)
+              replyMessage.addField(name:"text", value:"Swift nonstreaming echo " + field.string())
               requestHandler.sendResponse(message:ByteBuffer(data:replyMessage.serialize()),
                                           trailingMetadata:Metadata())
             }
@@ -74,13 +74,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {
         }
       }
 
+      // STREAMING
       if (requestHandler.method() == "/echo.Echo/Update") {
         requestHandler.sendMetadata(
           initialMetadata: Metadata(),
           completion: {
+
             self.handleMessage(
               fileDescriptorSet: fileDescriptorSet,
               requestHandler: requestHandler)
+
+            // we seem to never get this, but I'm told it's what we're supposed to do
             requestHandler.receiveClose() {
               requestHandler.sendStatus(trailingMetadata: Metadata(), completion: {
                 print("status sent")
@@ -99,20 +103,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
     requestHandler.receiveMessage()
       {(requestBuffer) in
         if let requestBuffer = requestBuffer,
-          let requestMessage =
-          fileDescriptorSet.readMessage(name:"EchoRequest",
-                                        proto:requestBuffer.data()) {
+          let requestMessage = fileDescriptorSet.readMessage(name:"EchoRequest",
+                                                             proto:requestBuffer.data()) {
           requestMessage.forOneField(name:"text") {(field) in
             let replyMessage = fileDescriptorSet.createMessage(name:"EchoResponse")!
-            let text = "Swift streaming echo " + field.string()
-            replyMessage.addField(name:"text", value:text)
-            requestHandler.sendResponse(
-            message:ByteBuffer(data:replyMessage.serialize())) {
+            replyMessage.addField(name:"text", value:"Swift streaming echo " + field.string())
+            requestHandler.sendResponse(message:ByteBuffer(data:replyMessage.serialize())) {
+              // after we've sent our response, prepare to handle another message
               self.handleMessage(fileDescriptorSet:fileDescriptorSet, requestHandler:requestHandler)
             }
           }
         } else {
-          // an empty message means close the connection
+          // if we get an empty message (nil buffer), we close the connection
           requestHandler.sendStatus(trailingMetadata: Metadata(), completion: {
             print("status sent")
             requestHandler.shutdown()

+ 4 - 1
Examples/Echo/Swift/Echo/Base.lproj/MainMenu.xib

@@ -105,7 +105,7 @@
             <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="335" y="390" width="400" height="179"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
             <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
                 <rect key="frame" x="0.0" y="0.0" width="400" height="179"/>
                 <autoresizingMask key="autoresizingMask"/>
@@ -139,6 +139,9 @@
                             <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
                             <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                         </textFieldCell>
+                        <connections>
+                            <action selector="addressReturnPressedWithSender:" target="8aG-cq-jvr" id="LPA-g7-vIb"/>
+                        </connections>
                     </textField>
                     <button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5WD-rH-7rC">
                         <rect key="frame" x="18" y="18" width="84" height="25"/>

+ 11 - 5
Examples/Echo/Swift/Echo/EchoViewController.swift

@@ -58,6 +58,13 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     }
   }
 
+  @IBAction func addressReturnPressed(sender: NSTextField) {
+    if (streaming) {
+      print ("stop streaming")
+      self.sendClose()
+    }
+  }
+
   @IBAction func buttonValueChanged(sender: NSButton) {
     print("button value changed \(sender)")
     if (streaming && (sender.intValue == 0)) {
@@ -85,8 +92,8 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     gRPC.initialize()
 
     if (self.streamingButton.intValue == 0) {
+      // NONSTREAMING
       client = Client(address:address)
-      self.client!.completionQueue.run() {}
 
       DispatchQueue.global().async {
         // build the message
@@ -123,9 +130,10 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
       }
     }
     else {
+      // NONSTREAMING
+
       if (!streaming) {
         client = Client(address:address)
-        self.client!.completionQueue.run() {}
 
         call = client?.createCall(host: "foo.test.google.fr",
                                   method: "/echo.Echo/Update",
@@ -134,7 +142,7 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
         self.sendInitialMetadata()
         self.receiveInitialMetadata()
         self.receiveStatus()
-        self.receiveMessage()
+        self.receiveMessage() // this should take a block in which we specify what to do
         streaming = true
       }
       self.sendMessage()
@@ -243,5 +251,3 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     }
   }
 }
-
-

+ 0 - 3
Packages/CgRPC/Sources/cgrpc.h

@@ -156,9 +156,6 @@ cgrpc_completion_queue *cgrpc_handler_get_completion_queue(cgrpc_handler *h);
 grpc_call_error cgrpc_handler_request_call(cgrpc_handler *h,
                                            cgrpc_metadata_array *metadata,
                                            long tag);
-grpc_event cgrpc_handler_wait_for_request(cgrpc_handler *h,
-                                          cgrpc_metadata_array *metadata,
-                                          double timeout);
 const char *cgrpc_handler_host(cgrpc_handler *h);
 const char *cgrpc_handler_method(cgrpc_handler *h);
 const char *cgrpc_handler_call_peer(cgrpc_handler *h);

+ 0 - 20
Packages/CgRPC/Sources/handler.c

@@ -96,23 +96,3 @@ grpc_call_error cgrpc_handler_request_call(cgrpc_handler *h,
 }
 
 
-grpc_event cgrpc_handler_wait_for_request(cgrpc_handler *h,
-                                          cgrpc_metadata_array *metadata,
-                                          double timeout) {
-  void *tag101 = cgrpc_create_tag(101);
-  grpc_call_error error = grpc_server_request_call(h->server->server,
-                                                   &(h->server_call),
-                                                   &(h->call_details),
-                                                   metadata,
-                                                   h->completion_queue,
-                                                   h->server->completion_queue,
-                                                   tag101);
-  assert(error == GRPC_CALL_OK);
-
-  // wait for a request
-  return cgrpc_completion_queue_get_next_event(h->server->completion_queue, timeout);
-}
-
-
-
-

+ 5 - 9
Packages/gRPC/Sources/Call.swift

@@ -49,6 +49,9 @@ public class Call {
   /// Pointer to underlying C representation
   private var call : UnsafeMutableRawPointer!
 
+  /// Completion queue used for call
+  private var completionQueue: CompletionQueue
+
   /// True if this instance is responsible for deleting the underlying C representation
   private var owned : Bool
 
@@ -56,17 +59,10 @@ public class Call {
   ///
   /// - Parameter call: the underlying C representation
   /// - Parameter owned: true if this instance is responsible for deleting the underlying call
-  init(call: UnsafeMutableRawPointer, owned: Bool) {
+  init(call: UnsafeMutableRawPointer, owned: Bool, completionQueue: CompletionQueue) {
     self.call = call
     self.owned = owned
-  }
-
-  // coming soon
-  init(call: UnsafeMutableRawPointer,
-       requestsWriter: Writer,
-       responsesWritable: Writable) {
-    self.call = call
-    self.owned = true
+    self.completionQueue = completionQueue
   }
 
   deinit {

+ 3 - 2
Packages/gRPC/Sources/Client.swift

@@ -49,7 +49,8 @@ public class Client {
   public init(address: String) {
     c = cgrpc_client_create(address)
     completionQueue = CompletionQueue(cq:cgrpc_client_completion_queue(c))
-    completionQueue.name = "Client"
+    completionQueue.name = "Client" // only for debugging
+    self.completionQueue.run() {} // start a loop that watches the queue
   }
 
   deinit {
@@ -64,7 +65,7 @@ public class Client {
   /// - Returns: a Call object that can be used to make the request
   public func createCall(host:String, method:String, timeout:Double) -> Call {
     let call = cgrpc_client_create_call(c, method, host, timeout)!
-    return Call(call:call, owned:true)
+    return Call(call:call, owned:true, completionQueue:self.completionQueue)
   }
 
   /// Performs a nonstreaming gRPC API call

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

@@ -85,7 +85,9 @@ public class Handler {
   ///
   /// - Returns: a Call object that can be used to respond to the request
   func call() -> Call {
-    return Call(call: cgrpc_handler_get_call(h), owned:false)
+    return Call(call: cgrpc_handler_get_call(h),
+                owned: false,
+                completionQueue: self.completionQueue)
   }
 
   /// Request a call for the handler