]> asedeno.scripts.mit.edu Git - cl-protobufs.git/commitdiff
Lose the 'response' argument from the RPC stubs, it's not needed in Lisp
authorScott McKay <swm@google.com>
Mon, 27 Aug 2012 20:58:19 +0000 (20:58 +0000)
committerScott McKay <swm@google.com>
Mon, 27 Aug 2012 20:58:19 +0000 (20:58 +0000)
git-svn-id: http://svn.internal.itasoftware.com/svn/ita/trunk/qres/lisp/libs/cl-protobufs@559035 f8382938-511b-0410-9cdd-bb47b084005c

cl-protobufs.rst
define-proto.lisp
model-classes.lisp

index 2f623b59bdabbf02782e1a79140a68a5f92f978c..ffdbd556e6ab34d84f3fa1de35eb7eea8348549a 100644 (file)
@@ -501,7 +501,7 @@ Fields take the form ``(slot &key type name default reader writer)``.
 *slot* can be either a symbol giving the slot name or a list of the
 form ``(slot index)``. By default, the field indexes start at 1 and
 are incremented by 1 for each new field value. *type* is the type of
-the slot.  For schema forward and backward compatibility, you should
+the slot. For schema forward and backward compatibility, you should
 always use the ``(slot index)`` form.
 
 *name* can be used to override the defaultly generated Protobufs field
@@ -650,17 +650,17 @@ Protobufs service stubs
 
 When you use the ``proto:define-service`` macro to define a service
 with some methods, the macro defines "stubs" (CLOS generic functions)
-for each of the methods in the service. Each method gets a client stub
-and a server stub whose signatures are, respectively::
+for each of the methods in the service. Each method named ``foo`` gets
+a client stub and a server stub whose signatures are, respectively::
 
-  (rpc-channel input output &key callback) => output
-  (rpc-channel input output) => output
+  foo    (rpc-channel request &key callback) => response
+  do-foo (rpc-channel request) => response
 
 The type of *rpc-channel* is unspecified, but is meant to be a
-"channel" over which some sort of RPC call will be done. The types of
-*input* and *output* are classes that were defined via
+"channel" over which the RPC call will be done. The types of *request*
+and *response* are message classes that were defined via
 Protobufs. *callback* is a function of two arguments, the RPC channel
-and the output; it is intended for use by asynchronous RPC calls.
+and the response; it is intended for use by asynchronous RPC calls.
 
 For example, this fragment defines four stubs::
 
@@ -673,6 +673,20 @@ are ``do-get-color`` and ``do-add-color``. An RPC library will implement
 a method for the client stub. You must fill in the server stub yourself;
 it will implement the desired functionality.
 
+The client stub also gets a single method defined for it that looks like
+something like this::
+
+  (defmethod foo (rpc-channel (request input-type) &key callback)
+    (let ((call (and *rpc-package* *rpc-call-function*)))
+      (funcall call rpc-channel method request :callback vcallback)))
+
+where *rpc-channel*, *request* and *callback* are as above.
+The special variables ``*rpc-package*`` and ``*rpc-call-function*``
+are filled in when the RPC package is loaded. *method* is the
+``proto:protobuf-method`` that describes the method; this is
+included so that the RPC implementation can determine what type
+of response object to create, what timeout to use, etc.
+
 It is beyond the scope of this Protobufs library to provide the RPC
 service; that is the domain of another library.
 
index 5ff3370a3f4a9f01565ddac09ef4317f4ba26507..897800a10723ea618011e9ef9f91a9f2d0c7f206 100644 (file)
                             :documentation documentation
                             :source-location source-location)))
             (setf (proto-methods service) (nconc (proto-methods service) (list method)))
-            ;; The following are the hooks to CL-Stubby
-            (let* ((vinput    (intern (format nil "~A-~A" (symbol-name input-type) 'in) package))
-                   (voutput   (intern (format nil "~A-~A" (symbol-name output-type) 'out) package))
+            ;; The following are the hooks to an RPC implementation
+            (let* ((vrequest  (intern (symbol-name 'request) package))
                    (vchannel  (intern (symbol-name 'channel) package))
                    (vcallback (intern (symbol-name 'callback) package)))
               ;; The client side stub, e.g., 'read-air-reservation'.
-              ;; The expectation is that CL-Stubby will provide macrology to make it
+              ;; The expectation is that the RPC implementation will provide code to make it
               ;; easy to implement a method for this on each kind of channel (HTTP, TCP socket,
               ;; IPC, etc). Unlike C++/Java/Python, we don't need a client-side subclass,
               ;; because we can just use multi-methods.
-              ;; The CL-Stubby macros take care of serializing the input, transmitting the
+              ;; The 'do-XXX' method calls the RPC code with the channel, the method
+              ;; (i.e., a 'protobuf-method' object), the request and the callback function.
+              ;; The RPC code should take care of serializing the input, transmitting the
               ;; request over the wire, waiting for input (or not if it's asynchronous),
-              ;; filling in the output, and calling the callback (if it's asynchronous).
-              ;; It's not very Lispy to side-effect an output object, but it makes
-              ;; asynchronous calls simpler.
-              (collect-form `(defgeneric ,client-fn (,vchannel ,vinput ,voutput &key ,vcallback)
+              ;; filling in the output, and either returning the response (if synchronous)
+              ;; or calling the callback with the response as an argument (if asynchronous).
+              ;; It will also deserialize the response so that the client code sees the
+              ;; response as an application object.
+              (collect-form `(defgeneric ,client-fn (,vchannel ,vrequest &key ,vcallback)
                                ,@(and documentation `((:documentation ,documentation)))
                                #-sbcl (declare (values ,output-type))
-                               (:method (,vchannel (,vinput ,input-type) (,voutput ,output-type) &key ,vcallback)
+                               (:method (,vchannel (,vrequest ,input-type) &key ,vcallback)
                                  (declare (ignorable ,vchannel ,vcallback))
                                  (let ((call (and *rpc-package* *rpc-call-function*)))
                                    (assert call ()
                                            "There is no RPC package loaded!")
-                                   (funcall call ,vchannel ',method ,vinput ,voutput
+                                   (funcall call ,vchannel ',method ,vrequest
                                             :callback ,vcallback)))))
               ;; The server side stub, e.g., 'do-read-air-reservation'.
               ;; The expectation is that the server-side program will implement
               ;; a method with the business logic for this on each kind of channel
               ;; (HTTP, TCP socket, IPC, etc), possibly on a server-side subclass
-              ;; of the input class
+              ;; of the input class.
               ;; The business logic is expected to perform the correct operations on
               ;; the input object, which arrived via Protobufs, and produce an output
-              ;; of the given type, which will be serialized as a result.
+              ;; of the given type, which will be serialized and sent back over the wire.
               ;; The channel objects hold client identity information, deadline info,
-              ;; etc, and can be side-effected to indicate success or failure
-              ;; CL-Stubby provides the channel classes and does (de)serialization, etc
-              (collect-form `(defgeneric ,server-fn (,vchannel ,vinput ,voutput)
+              ;; etc, and can be side-effected to indicate success or failure.
+              ;; The RPC code provides the channel classes and does (de)serialization, etc
+              (collect-form `(defgeneric ,server-fn (,vchannel ,vrequest)
                                ,@(and documentation `((:documentation ,documentation)))
                                #-sbcl (declare (values ,output-type))))))))
       `(progn
index cfffd306f9f7fc9459f79b9999d04de07925249b..89337fcfe7853c1fd515a26a4010d922d699ba12 100644 (file)
           :initarg :output-name
           :initform nil)
    (index :type (unsigned-byte 32)              ;an identifying index for this method
-          :accessor proto-index                 ; (used by Stubby)
+          :accessor proto-index                 ; (used by the RPC implementation)
           :initarg :index))
   (:documentation
    "The model class that represents one method with a Protobufs service."))