summaryrefslogtreecommitdiff
path: root/lib/cl/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cl/README.md')
-rw-r--r--lib/cl/README.md253
1 files changed, 0 insertions, 253 deletions
diff --git a/lib/cl/README.md b/lib/cl/README.md
deleted file mode 100644
index 1d6eafbd7..000000000
--- a/lib/cl/README.md
+++ /dev/null
@@ -1,253 +0,0 @@
-Thrift Common Lisp Library
-
-License
-=======
-
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you 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.
-
-
-
-Using Thrift with Common Lisp
-============================
-
- Thrift is a protocol and library for language-independent communication between cooperating
- processes. The communication takes the form of request and response messages, of which the forms
- are specified in advance throufh a shared interface definition. A Thrift definition file is translated
- into Lisp source files, which comprise several definitions:
-
- * Three packages, one for the namespace of the implementation operators, and one each for request and
- response operators.
- * Various type definitions as implementations for Thrift typedef and enum definitions.
- * DEF-STRUCT and DEF-EXCEPTION forms for Thrift struct and exception definitions.
- * DEF-SERVICE forms for thrift service definitions.
-
- Each service definition expands in a collection of generic function definitions. For each `op`
- in the service definition, two functions are defined
-
- * `op`-request is defined for use by a client. It accepts an additional initial `protocol` argument,
- to act as the client proxy for the operation and mediate the interaction with a remote process
- through a Thrift-encoded transport stream.
- * `op`-response is defined for use by a server. It accepts a single `protocol` argument. A server
- uses it to decode the request message, invoke the base `op` function with the message arguments,
- encode and send the the result as a response, and handles exceptions.
-
- The client interface is one operator
-
- * `with-client (variable location) . body` : creates a connection in a dynamic context and closes it
- upon exit. The variable is bound to a client proxy stream/protocol instance, which wraps the
- base i/o stream - socket, file, etc, with an operators which implement the Thrift protocol
- and transport mechanisms.
-
- The server interface combines server and service objects
-
- * `serve (location service)` : accepts connections on the designated port and responds to
- requests of the service's operations.
-
-
-Building
---------
-
-The Thrift Common Lisp library is packaged as the ASDF[[1]] system `thrift`.
-It depends on the systems
-
-* puri[[2]] : for the thrift uri class
-* closer-mop[[3]] : for class metadata
-* trivial-utf-8[[4]] : for string codecs
-* usocket[[5]] : for the socket transport
-* ieee-floats[[6]] : for conversion between ints and floats
-* trivial-gray-streams[[7]] : an abstraction layer for gray streams
-* alexandria[[8]] : handy utilities
-
-The dependencies are bundled for local builds of tests and tutorial binaries -
-it is possible to use those bundles to load the library, too.
-
-In order to build it, register those systems with ASDF and evaluate:
-
- (asdf:load-system :thrift)
-
-This will compile and load the Lisp compiler for Thrift definition files, the
-transport and protocol implementations, and the client and server interface
-functions. In order to use Thrift in an application, one must also author and/or
-load the interface definitions for the remote service.[[9]] If one is implementing a service,
-one must also define the actual functions to which Thrift is to act as the proxy
-interface. The remainder of this document follows the Thrift tutorial to illustrate how
-to perform the steps
-
- * implement the service
- * translate the Thrift IDL
- * load the Lisp service interfaces
- * run a server for the service
- * use a client to access the service remotely
-
-Note that, if one is to implement a new service, one will also need to author the
-IDL files, as there is no facility to generate them from a service implementation.
-
-
-Implement the Service
----------------------
-
-The tutorial comprises serveral functions: `add`, `ping`, `zip`, and `calculate`.
-Each translated IDL file generates three packages for every service. In the case of
-the tutorial file, the relevant packages are:
-
- * tutorial.calculator
- * tutorial.calculator-implementation
- * tutorial.calculator-response
-
-This is to separate the request (generated), response (generated) and implementation
-(meant to be implemented by the programmer) functions for defined Thrift methods.
-
-It is suggested to work in the `tutorial-implementation` package while implementing
-the services - it imports the `common-lisp` package, while the service-specific ones
-don't (to avoid conflicts between Thrift method names and function names in `common-lisp`).
-
- ;; define the base operations
-
- (in-package :tutorial-implementation)
-
- (defun tutorial.calculator-implementation:add (num1 num2)
- (format t "~&Asked to add ~A and ~A." num1 num2)
- (+ num1 num2))
-
- (defun tutorial.calculator-implementation:ping ()
- (print :ping))
-
- (defun tutorial.calculator-implementation:zip ()
- (print :zip))
-
- (defun tutorial.calculator-implementation:calculate (logid task)
- (calculate-op (work-op task) (work-num1 task) (work-num2 task)))
-
- (defgeneric calculate-op (op arg1 arg2)
- (:method :around (op arg1 arg2)
- (let ((result (call-next-method)))
- (format t "~&Asked to calculate: ~d on ~A and ~A = ~d." op arg1 arg2 result)
- result))
-
- (:method ((op (eql operation.add)) arg1 arg2)
- (+ arg1 arg2))
- (:method ((op (eql operation.subtract)) arg1 arg2)
- (- arg1 arg2))
- (:method ((op (eql operation.multiply)) arg1 arg2)
- (* arg1 arg2))
- (:method ((op (eql operation.divide)) arg1 arg2)
- (/ arg1 arg2)))
-
- (defun zip () (print 'zip))
-
-
-Translate the Thrift IDL
-------------------------
-
-IDL files employ the file extension `thrift`. In this case, there are two files to translate
- * `tutorial.thrift`
- * `shared.thrift`
-As the former includes the latter, one uses it to generate the interfaces:
-
- $THRIFT/bin/thrift -r --gen cl $THRIFT/tutorial/tutorial.thrift
-
-`-r` stands for recursion, while `--gen` lets one choose the language to translate to.
-
-
-Load the Lisp translated service interfaces
--------------------------------------------
-
-The translator generates three files for each IDL file. For example `tutorial-types.lisp`,
-`tutorial-vars.lisp` and an `.asd` file that can be used to load them both and pull in
-other includes (like `shared` within the tutorial) as dependencies.
-
-
-Run a Server for the Service
-----------------------------
-
-The actual service name, as specified in the `def-service` form in `tutorial.lisp`, is `calculator`.
-Each service definition defines a global variable with the service name and binds it to a
-service instance whch describes the operations.
-
-In order to start a service, specify a location and the service instance.
-
- (in-package :tutorial)
- (serve #u"thrift://127.0.0.1:9091" calculator)
-
-
-Use a Client to Access the Service Remotely
--------------------------------------------
-
-
-[in some other process] run the client
-
- (in-package :cl-user)
-
- (macrolet ((show (form)
- `(format *trace-output* "~%~s =>~{ ~s~}"
- ',form
- (multiple-value-list (ignore-errors ,form)))))
- (with-client (protocol #u"thrift://127.0.0.1:9091")
- (show (tutorial.calculator:ping protocol))
- (show (tutorial.calculator:add protocol 1 2))
- (show (tutorial.calculator:add protocol 1 4))
-
- (let ((task (make-instance 'tutorial:work
- :op operation.subtract :num1 15 :num2 10)))
- (show (tutorial.calculator:calculate protocol 1 task))
-
- (setf (tutorial:work-op task) operation.divide
- (tutorial:work-num1 task) 1
- (tutorial:work-num2 task) 0)
- (show (tutorial.calculator:calculate protocol 1 task)))
-
- (show (shared.shared-service:get-struct protocol 1))
-
- (show (zip protocol))))
-
-Issues
-------
-
-### optional fields
- Where the IDL declares a field options, the def-struct form includes no
- initform for the slot and the encoding operator skips an unbound slot. This leave some ambiguity
- with bool fields.
-
-### instantiation protocol :
- struct classes are standard classes and exception classes are
- whatever the implementation prescribes. decoders apply make-struct to an initargs list.
- particularly at the service end, there are advantages to resourcing structs and decoding
- with direct side-effects on slot-values
-
-### maps:
- Maps are now represented as hash tables. As data through the call/reply interface is all statically
- typed, it is not necessary for the objects to themselves indicate the coding form. Association lists
- would be sufficient. As the key type is arbitrary, property lists offer no additional convenience:
- as `getf` operates with `eq` a new access interface would be necessary and they would not be
- available for function application.
-
-
- [1]: www.common-lisp.net/asdf
- [2]: http://github.com/lisp/com.b9.puri.ppcre
- [3]: www.common-lisp.net/closer-mop
- [4]: trivial-utf-8
- [5]: https://github.com/usocket/usocket
- [6]: https://github.com/marijnh/ieee-floats
- [7]: https://github.com/trivial-gray-streams/trivial-gray-streams
- [8]: https://gitlab.common-lisp.net/alexandria/alexandria
- [9]: http://wiki.apache.org/thrift/ThriftGeneration
-
-* usocket[[5]] : for the socket transport
-* ieee-floats[[6]] : for conversion between ints and floats
-* trivial-gray-streams[[7]] : an abstraction layer for gray streams
-* alexandria[[8]] : handy utilities