« Core Software Processes | Main | Migrating to Subversion IV »

ActiveMQ: RESTful JMS, sort of

Update: ActiveMQ's CVS HEAD now supports HTTP DELETE for consuming of messages (which has no timeout, it returns immediately). POST will return a globally unique URI for each message to enable reliable messaging/avoid duplicates. To which I say...

Open Source response times... Nice.


Is this implementation of queueing a good example of the ReST approach? - Patrick Logan

As a first cut the ActiveMQ guys have done a fair job; there is more they could do. In fairness, this is not so straighforward to get right, since modelling containers with URIs can be tricky. It's cool they're taking a principled approach.

In particular I am wondering about the use of GET to dequeue an item

If that's what they're doing, it's probably a bad idea (but I need to see the code to be sure). GET is for peeking rather than popping. Use POST/DELETE to dequeue. Otherwise if there is a cache between you and the origin server, you may get unexpected, silent, bugs when using GET insofar as a cache will interfere with expected JMS semantics. In the infrastructures I've worked with, this would cause issues.

It helps enormously if each entity being sent into a queue is supplied its own URI- you do this by returning a URI in the Location header. We've used this in Propylon to manage reliable delivery over HTTP; it's very handy when it comes to tracking messages, browsing queues and building reconcilliation reports. This gets much trickier if the client has to have intimate knowledge of the URI structure- computing them instead of dealing with them as opaque strings ups the odds that what I throw together will be ActiveMQ specific (this would be a bit like having a local version of JMX). Aside from that, URI per sent item can scale by suppyling a naturally distributed data structure; in theory it's better to allow random access to items than demanding all clients synchronize access via the controller (queue/topic) URI.

Update: James pointed out that this feature is for streamlets not mq, which is a different matter. I would lose the timeout feature. If there are no messages simply return that information. Holding a reference via keep-alive is a hack to emulate API callbacks - don't go there ;)

Finally, I wonder what they're doing around duplicate deliveries. The odds of that happening are much higher over HTTP than an inproc API call. I'll have to checkout the code to learn more - knowing Bob and James this will be a Maven build...

[jay z: lucifer]

May 27, 2004 02:01 PM


James Strachan
(May 27, 2004 07:27 PM #)

Agreed on the possible use of POST/DELETE for consuming messages. We'll definitely need to support this too.

Though to put things another way. Imagine you want to look at a market data price for IBM stock (say). On a normal website (dare I mention RSS) you'd do a GET and find the latest - then use HTTP headers to avoid cached copies etc.

So I do think GET is a valid approach (and the easiest one to test, just use a web browser!) but yes I think we need a more complex approach to a truely RESTful JMS - its pretty trivial to change to be 'true'. Part of the reason for making the current implementation public in the blogosphere was to get that discussion going on what that ideal RESTful JMS should be like.

BTW the keep-alive is purely there for Streamlets support (web streaming). Its up to the client to use it or not (or for the server to allow it or not).

BTW2 sorry, its a Maven build :)

James Strachan
(May 27, 2004 07:47 PM #)

Thanks for the suggestions Bill.

CVS HEAD now supports HTTP DELETE for consuming of messages (which has no timeout, it returns immediately).

Also a POST will return a globally unique URI for each message to allow reliable messaging (avoiding duplicates).

Ian Lim
(May 31, 2004 03:58 PM #)

Anybody care to enlighten me where is ActiveMQ located? This is the first time I heard of it :)

Jon Hanna
(June 1, 2004 09:47 AM #)

I have to disagree with James' defense of the use of GET here in what seems like an otherwise wonderful design.
It is part of the semantics of GET that it is safe; I can GET to my heart's content and I won't change what I'm GETting. Caches aren't the only tools that rely on this guarantee. And even if only custom tools are used changing the semantics of GET means you aren't playing HTTP any more.
I would go for having either a POST for popping or using a GET & DELETE sequence, much like using the queues in C++'s STL, which uses a peek followed by a blind pop (that is a pop that doesn't return the thing popped), indeed that's a reasonably good comparison given that in the STL model the peek part of that operation can be done on a const queue.
I'd be tempted to offer the user the choice of whether to use POST or GET followed by DELETE, though the latter sequence is likely more robust in the case of partial failure.

Trackback Pings

TrackBack URL for this entry: