Code Monkey home page Code Monkey logo

de.setf.amqp's Introduction

DE.SETF.AMQP: a Common Lisp client library for AMQP

de.setf.amqp implements a native Common Lisp client library for the 'Advanced Message Queuing Protocol' (AMQP). The implementation comprises wire-level codecs, implementations for the standard protocol objects and methods, a functional interface for message-, stream- and object-based i/o, and a device-level simple-stream implementation.

The library targets the revisions of the published AMQP protocol as of versions 0.8, 0.9, and 0.10. This means that it should work with respective RabbitMQ, OpenAMQ, and Qpid implementations. The implementation architecture should also accommodate a control structure appropriate for the prospective 1.0 version - as least as described in preliminary drafts. For each version, a distinct package comprises the object and method definitions for protocol entities and codecs as generated from the respective specification documents.[1] Each collection is a complete projection, which means there is some amount of duplication. The names - classes, operators, fields, packages and directories all follow more-or-less the naming conventions of the xml protocol documents[2]:

AMQP-1-1-0-8-0 version 0.8 [amqp0-8.xml, amqp0-8.pdf (2006-06)]
AMQP-1-1-0-9-0 version 0.9 [amqp0-9.xml, amqp0-9.pdf (2006-12)]
AMQP-1-1-0-9-1 version 0.9r1 [amqp0-9-1.xml, amqp0-9-1.pdf (2008-11-24)]
AMQP-1-1-0-10-0 version 0.10 [amqp.0-10.xml, amqp.0-10.pdf (2008-02-20)]

In order to modify the translation and/or generate new codecs consult the :de.setf.amqp.tools module.

All protocol versions are expressed through a common interface[3] which is specialized for the common abstract classes. The initial connection phase determines the correct concrete connection implementation to be used to communicate with the broker. Given which the other concrete object and method classes are elected from the same package. One determines the version to be supported directly by loading the respective version's .asd file, which makes its connection class available for negotiation.

Status

This is intended as the base for a distributed semantic store. What one has here is a reasonably complete engineering prototype. It consumes phenomenal amounts of memory and runs astonishingly slowly: 5 - 10 milliseconds and 1 to 10 thousand bytes per round trip. A request entails ten levels of generic function dispatch, half of which require keyword processing. A response call stack is about as deep, but with somewhat less keyword processing. As almost everything between the interface commands and the frame buffers is generated code, once it is clear which aspects should remain available for specialization and/or optional arguments, the protocol call stack would benefit from recasting uninteresting elements as ordinary functions of fixed arguments - depending on implementation type, by a factor of ten to sixty.

It would also be nice to generate a table similar to RabbitMQ's to record protocol conformance and compatibility with brokers. Eventually. The present tests are limited to

  • codec unit tests which validate the respective version's codecs for default argument values.
  • in-memory loop-back tests, used to ensure (for a recent version) that a round-trip does not cons
  • simple data exchanges with a broker.

An Example

The library has been built and probed in the following combinations

AMQP broker
lisp implementation
RabbittMQQPID
MCLMCL-5.2, RabbitMQ 1.7.1, AMQP-0.8r0MCL-5.2, QPID-0.5, AMQP-0.9r1
CCLCCL-1.4, QPID-0.5, AMQP-0.9r1
SBCLSBCL-1.0.35, QPID-0.5, AMQP-0.9r1

For example,

$ sbcl
This is SBCL 1.0.35, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

* (in-package :amqp.i)

#<PACKAGE "DE.SETF.AMQP.IMPLEMENTATION">
* (defparameter *c* (make-instance 'amqp:connection :uri "amqp://guest:guest@localhost/"))

*C*
* (defparameter *ch1* (amqp:channel *c* :uri (uri "amqp:///")))

*CH1*
* (defparameter *ch1.basic* (amqp:basic *ch1*))

*CH1.BASIC*
* (defparameter *ch1.ex* (amqp:exchange *ch1*  :exchange "ex" :type "direct"))

*CH1.EX*
* (defparameter *ch1.q*  (amqp:queue *ch1* :queue "q1"))

*CH1.Q*
* (amqp:request-declare *ch1.q*)

#<AMQP-1-1-0-9-1:QUEUE {11D7A0F1}>
* (amqp:request-bind *ch1.q* :exchange *ch1.ex* :queue *ch1.q* :routing-key "/")

#<AMQP-1-1-0-9-1:QUEUE {11D7A0F1}>
* (defparameter *ch2* (amqp:channel *c* :uri (uri "amqp:///")))

*CH2* 
* (defparameter *ch2.basic* (amqp:basic *ch2*))

*CH2.BASIC*
* (defparameter *ch2.q*  (amqp:queue *ch2* :queue "q1"))

*CH2.Q*
* (amqp:request-declare *ch2.q*)

#<AMQP-1-1-0-9-1:QUEUE {11DA6891}>
* (list
    (amqp:request-publish *ch1.basic* :exchange *ch1.ex*
                          :body (format nil "this is ~a" (gensym "test #"))
                          :routing-key "/")
    (amqp:request-get *ch2.basic* :queue *ch2.q*))

("this is test #1282" "this is test #1624")
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #1820"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #1998"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #2011"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #2014"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #2022"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #2028"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #2179"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

"this is test #1282"
* (amqp:request-get *ch2.basic* :queue *ch2.q*)

NIL
* 

Which, as an aside, illustrates that brokered messages persist between connections until they have been consumed. Of which a default QPID broker with no persistence support was observed to cache only about 500k bytes (ca. 25,000 messages of 20 bytes each).

An introduction to the API is taking shape. In the meantime, there is a package index, there are a few examples for the library proper and for the RabbitMQ library emulation.

common-lisp.net hosts a mailing list and a trac instance for discussions and/or reports.

Changes

  • 2010-06-10 : corrected and completed float codecs
  • 2011-11-20 : added user-id default for publish to cooperate with rabbitmq @2.6

Downloading

A .dmg is available for MCL-5.2. Saved images are available for ccl and sbcl.

Building

In principle, de.setf.amqp is built with asdf. Once one has the sources and the asdf configuration in place, evaluate

(asdf:operate 'asdf:load-op :de.setf.amqp.amqp-1-1-0-8-0)
(asdf:operate 'asdf:load-op :de.setf.amqp.amqp-1-1-0-9-0)
(asdf:operate 'asdf:load-op :de.setf.amqp.amqp-1-1-0-9-1)

to load the respective version. The versions intend to be compatible and connections should negotiate automatically to use the correct implementation. Please consult the detailed instructions for the respective runtime for more information.

Licensing

This version is released under version 3 of the GNU Affero license (GAL).[5] The required components are included as per the respective licenses and covered, in this combined form, under the GAL as well


made with mcl

de.setf.amqp's People

Contributors

lisp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

de.setf.amqp's Issues

Not included in Quicklisp

Hi,

I am interested in using your library with RabbitMQ and SBCL 1.0.57; however, it isn't in Quicklisp. It would be really nice if it was in Quicklisp.

If there's anything I can do to help you out there, let me know.

regards,
Paul

Build and core fail on SBCL 1.2.2

Has this been abandoned? Can't build from source nor load the core :\

jackc@petrichor ~/dev/cl/var/amqp/de.setf.amqp $ sbcl --userinit readmes/build-init.lisp \
>   --eval "(asdf:operate 'asdf:load-op :de.setf.amqp.amqp-1-1-0-8-0)" \
>   --eval "(asdf:operate 'asdf:load-op :de.setf.amqp.amqp-1-1-0-9-0)" \
>   --eval "(asdf:operate 'asdf:load-op :de.setf.amqp.amqp-1-1-0-9-1)" \
>   --eval '(sb-ext:save-lisp-and-die "sbcl-amqp.core")'
This is SBCL 1.2.2, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.

;Build root: #P"/Users/jackc/dev/cl/var/amqp/de.setf.amqp/".
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {1002C0F3C3}>:
  ASDF is missing: #P"/Users/jackc/dev/cl/var/amqp/de.setf.amqp/net/common-lisp/asdf/asdf.lisp".

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] Continue anyway.
  1: [RETRY   ] Retry EVAL of current toplevel form.
  2:            Ignore error and continue userinit file "/Users/jackc/dev/cl/var/amqp/de.setf.amqp/readmes/build-init.lisp".
  3: [ABORT   ] Abort userinit file "/Users/jackc/dev/cl/var/amqp/de.setf.amqp/readmes/build-init.lisp".
  4:            Skip to toplevel READ/EVAL/PRINT loop.
  5: [EXIT    ] Exit SBCL (calling #'EXIT, killing the process).

(SB-INT:SIMPLE-EVAL-IN-LEXENV (COND (T (CERROR "Continue anyway." "ASDF is missing: ~s." *ASDF-PATHNAME*))) #<NULL-LEXENV>)
0] 
jackc@petrichor ~/dev/cl/var/amqp $ sbcl --core sbcl-amqp.core
This is SBCL 1.2.2, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
fatal error encountered in SBCL pid 66926(tid 140735240332048):
invalid magic number in core: 0x140f00004c434253 should have been 0x5342434c.


Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb> 
CL-USER> (ql:system-apropos 'amqp)

; No value
CL-USER> (ql:system-apropos 'setf)
#<SYSTEM wilbur / de.setf.wilbur-20130128-git / quicklisp 2015-05-05>
; No value
CL-USER> 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.