I’ve updated our STOMP adapter for RabbitMQ to fix a bug reported by Carl Bourne. In the process, I updated the code to work with the latest snapshots of RabbitMQ, including the currently-released version, v1.3.0.
You can get the code by checking it out from our repository with
hg clone http://hg.opensource.lshift.net/rabbitmq-stomp/
hg update rabbitmq_v1_3_0_branch
or you can instead download a snapshot of the current state of the adapter[1], currently at revision 392d8cc8449c.
(Update: I forgot to mention that the mercurial repository has two branches in it: default, which tracks our internal RabbitMQ server repository, and rabbitmq_v1_3_0_branch, which should stay compatible with the 1.3.0 server release. Thanks to Aman Gupta, who pointed out the problem in a comment below!)
Here’s a summary of how to build and run a STOMP-enabled RabbitMQ broker - for more details, see the original post on the topic:
First, retrieve the RabbitMQ server 1.3.0 source code, and unpack it:
curl http://www.rabbitmq.com/releases/source/rabbitmq-1.3.0.tar.gz | tar -zxvf -
Next, grab the latest STOMP adapter (here we download a copy of the rabbitmq_v1_3_0_branch rather than the main trunk):
curl http://hg.opensource.lshift.net/rabbitmq-stomp/archive/rabbitmq_v1_3_0_branch.tar.gz | tar -zxvf -
Compile the server itself:
make -C rabbitmq-1.3.0/erlang/rabbit
Finally, compile the adapter, and start the server with extra options that cause the adapter to start too:
make -C rabbitmq-stomp-rabbitmq_v1_3_0_branch run
If this is successful, you should end up with “starting STOMP-listeners …done” and “broker running” in your terminal. At this point you can try out the service - for instance, you can run Carl’s test cases if you have ruby and rubygems handy:
sudo apt-get install ruby
sudo apt-get install rubygems
sudo gem install stomp
ruby rabbitmq-stomp-rabbitmq_v1_3_0_branch/priv/tests-ruby/cb-receiver.rb
and in another window
ruby rabbitmq-stomp-rabbitmq_v1_3_0_branch/priv/tests-ruby/cb-sender.rb
It will transfer 10,000 short messages, and end up displaying
...
Test Message number 9998
Test Message number 9999
All Done!
in the receiver-side terminal.
If you’re interested in the gory details of the bug-fix itself, you can see the relevant patch here. The problem was that the code that handled abrupt socket closure wasn’t handshaking with enough of the internals of the server to ensure that the last few work items were being processed successfully. Trapping socket closure in the STOMP adapter code, and politely handshaking, turned out to be all that was required. An alternative workaround would be to use STOMP’s DISCONNECT method before closing the socket on the client side.
Footnote 1: Note that despite the misleading URL, the snapshot download really is of the STOMP adapter, and not of the broker itself! I’m making use of hgwebdir’s archive-download feature here.
April 30th, 2008
tonyg
I’ve written
before, to no acclamation, about the difficulty in factoring
CSS. After more talking to and working with people who use CSS a lot more than
I do (and are commensurately more skillful), I think the difficulty
is the level of abstraction: CSS is declarative, but it is not
very abstract.
Usually the idea with declarative
languages is to describe the desired outcome and let the
computer do the figuring out how. CSS only deals with mechanism.
It does abstract from the how of layout and rendering; but, I would
argue, not in a very useful way: I want to say “make sure
this image lines up”, but what I can express is “nudge the image
down by ten pixels”.
It is like navigating in a rocket ship by manually controlling the
thrusters, when a computer is perfectly capable of working out the
whole thing ahead of time. (Of course you may want to pilot the
rocket ship manually for fun’s sake – Jef Raskin noted that
lack of expressiveness was what made games fun and most other
human-computer interfaces rubbish.)
However: CSS is what we have. What can we do to make it a better tool?
We can add the ability to express intent. The simplest example is
with constants: if I could write
@let COLUMN_WIDTH: 200px;
#foo {
width: COLUMN_WIDTH;
}
#bar {
margin-left: COLUMN_WIDTH;
}
it makes it obvious that the margin and the width are deliberately the
same. It also means that a value only needs to be
given in one place – handy for colour schemes.
Once there are symbolic values, it follows to have
expressions in value position. This is useful for layouts that
involve margins and widths in some combination:
margin-left: COLUMN_ONE_WIDTH + COLUMN_TWO_WIDTH.
Another way to increase bang for syntactic buck is to add in the
ability to abstract idiom: instead of
.box .c,
.box .t,
.box .b,
.box .b div {
background: transparent url(../img/extra-box-bg.gif) no-repeat top right;
}
#glass .box .c,
#glass .box .t,
#glass .box .b,
#glass .box .b div {
background: transparent url(../img/timeline-box-bg.png) no-repeat top right;
}
.side .box .c,
.side .box .t,
.side .box .b,
.side .box .b div {
background: transparent url(../img/side-box-bg.gif) no-repeat top right;
}
we could have
@def rounded(SELECTOR, BG) {
SELECTOR .c,
SELECTOR .t,
SELECTOR .b,
SELECTOR .b div {
background: transparent url(BG) no-repeat top right;
}
rounded(.box, ../img/extra-box-bg.gif);
rounded(#glass .box, ../img/timeline-box-bg.png);
rounded(.side .box, ../img/side-box-bg.gif);
Of course, it is easy enough to write a program to generate CSS
using some general-purpose programming language, or even a
templating language; but I think it will be more fruitful to grow
the established language outwards. Doing so maintains hygeine
– avoiding pitfalls of the “building SQL strings” kind, for
example – and allows for analysis.
This is all wishfulware until someone makes it happen. Since I can’t
much influence the specifications or browser implementations, I’m
working on a compiler that targets plain-old CSS. Elsewhere, there
is a
proposal for adding constants to CSS, and a proposed mechanism for
rule reuse.
April 30th, 2008
mikeb
(Continued from Moving away from CVS)
The wealth of options for a replacement for CVS presents us with a problem. We can’t choose a version control system by comparing feature lists: what seems perverse when presented in the manual may become natural in real use (which is the reaction many have to CVS’s “merge-don’t-lock” way of working at first), and contrarily what seems attractive on paper may prove problematic in real use (the system may claim sophisticated merging, but will it actually do what you want given your version history?). Equally, however, trying to use every system in anger would impose a very serious cost: unless we write the infrastructure for every system we test, some live project will have to do without it while they try out the shiny new system, and for every system someone will have to undergo the considerable expense of really learning how to use it and make it behave well. So we have to find ways to at least thin the candidate list.
Continue Reading April 30th, 2008
Paul Crowley