qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rafael Schloming <...@alum.mit.edu>
Subject events work and demo (How to implement your own broker in < 100 lines of code)
Date Wed, 02 Jul 2014 19:24:23 GMT
Hi Everyone,

Apologies for being a bit quiet recently. I've been heads down working on
some improvements to the events API. I've put together a little demo that
showcases what I've been doing.

Apologies for the teaser, but I'd like to encourage people to have a look.
;-) You can find the code for the demo on github:

    https://github.com/rhs/qpid-proton-demo/

Please note that if you want to run it yourself it depends on the events
branch which you can also find in my github repo:

    https://github.com/rhs/qpid-proton/tree/events

Much of the events work is already landed on trunk, however I've kept a few
final commits on my github events branch since they include some small but
incompatible API changes. (I'll post more about this separately.)

The demo is written both in Java and in Python. Both implementations are
(mostly) identical, so please peruse whichever you are most comfortable
reading. The python code is broken down into four files:

    spout, drain, server, and common.py

The Java code is similarly broken down:

    Spout.java, Drain.java, and Server.java plus a number of additional
.java files providing equivalents to the common.py module.

The spout and drain programs function as you might expect. Spout is a
simple producer of messages, drain is a simple consumer of messages. The
server program functions as a sort of hybrid broker/router thing. It
doesn't have explicitly defined queues, however it will store and forward
any messages sent to it and maintain the ordering of messages directed to a
given address. This is kind of like a broker that will automatically create
any queue when the first message arrives and automatically delete any queue
when the last message leaves.

The server doesn't take any args and will just listen on localhost port
5672:

  ~/demo$ ./server

Spout takes an address and a count:

  ~/demo$ ./spout //localhost/foo 10

Drain also takes an address and a count and by default will exit if there
are no messages available:

  ~/demo$ ./drain //localhost/foo 10

If you want it to wait for messages you can use the -b flag:

  ~/demo$ ./drain //localhost/foo 10 -b


The stuff in common.py and the equivalent .java counterparts provide a
supporting toolkit used by all three programs. Much of the stuff the
toolkit provides should be improved/expanded and pulled into the proton
library itself.

My goal with this demo has been to explore a couple of distinct themes. The
toolkit is intended in part to illustrate how the events API allows use of
proton in a reactive programming style. It does this by building a
select/nio based Driver that functions as a simple reactor. This is useful
in its own right, however it is also intended to serve as an example of how
you can integrate proton's events into an existing selector based
implementation.

Another big theme is providing the ability to encapsulate different aspects
of protocol behaviour into distinct but composable chunks. This is achieved
because the Driver dispatches each event to a configurable set of handlers.
This allows the Collector to serve as a central "event bus" and allows the
various handlers to all tie into this bus and work together to provide
useful combinations of behaviour.

Ultimately I hope this work will address the gap that we've had between the
simple/easy to use Messenger API and the experts-only Engine API. I believe
with a relatively small amount of work on a toolkit like this, the
internals of Messenger can be fairly trivially expressed as a composition
of different protocol behaviours, thereby allowing a simple and easy
starting point that can smoothly transition to any level of sophistication
desired.

Sorry for the long spiel. Please have a look and let me know what you think.

--Rafael

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message