| Author |
Message |
|
| Guest |
Posted: Wed May 28, 2008 12:56 pm |
|
|
|
Guest
|
Hi all,
I was pleased to find a STOMP broker to rabbitmq is under works,
however the default queue creation parameters didn't meet my initial
assumptions for using the broker as a reliable task dispatcher.
Digging through the code, I found that the queues were always being
created as non-durable and auto-deleted - any persistent messages
would be discarded when no consumers were subscribed. For our
application, we needed to save these messages and process them at well
defined intervals as well as have restart tolerant reliability.
Attached are 2 patches from my findings on how to expose some of the
method parameters as STOMP headers. They include the following changes:
* utility function to extract boolean header values
* expose 'passive', 'durable', 'auto-delete', 'exclusive' parameters
of the AMQP 'queue.declare' method as STOMP headers in SUBSCRIBE
* persist non AMQP binary content properties
* test sender and receiver for durable queues
The simple reproduction case is as follows:
* Connect a consumer and subscribe with the following headers:
SUBSCRIBE
destination: /queue/test
auto-delete: false
durable: true
* Disconnect the consumer
* Start a producer and send some persistent messages:
SEND
destination: /queue/test
delivery-mode: 2
content-length: 5
content-type: text/plain
ohai!
* Connect a consumer and subscribe to the queue with any headers
You should receive the persisted message sent to /queue/test. There
are 2 files in priv/tests-ruby that show this behavior a little bit
better. Comments are in persistent-sender.rb.
I also found a bug in message persistence over server restarts in
rabbitmq-1.3.0. In the comments for the content record, it states
that at most, one of properties and properties_bin can be 'none'.
During message persistence, it looked like there was an assumption
that all properties came from AMQP binary packed blobs and the parsed
headers were always cleared without checking that they could be
restored later. This patch will maintain the existing content/
properties when properties_bin is 'none'. As well as fixing the stomp
broker, this may fix persistence bugs with other erlang brokers that
speak directly to rabbit_channel:do/3.
Without the patch, when the durable queues were restored and the
persisted messages were resent, the content properties (including the
STOMP headers) were lost and no longer matched by
rabbit_stomp:send_reply/3 - logging an error and consuming the
message. With the patch, the persisted messages are are properly
restored and resent to the first subscriber.
To reproduce this:
Run persistent-receiver.rb once - interrupt.
Run persistent-sender.rb once
Stop all running nodes of rabbitmq
Start rabbitmq
Run persistent-receiver.rb - you should receive the messages
Big thanks to you all at LShift for building this beautiful code. My
familiarity with AMQP is still fresh so feedback on the applicability
of these patches is very welcome. Points I am unsure about are - the
role of the 'passive' parameter to queue.declare, whether or not to
expose the 'nowait' parameter, whether or not to try and match
ActiveMQ's STOMP header names or stick with the AMQP naming,
interoperability of the properties patch for brokers such as HTTP and
regression of the properties patch against AMQP messages with binary
properties. Also, the STOMP spec gives no insight for queue deletion
when a durable queue is no longer needed. Any ideas for that one?
Thanks,
-Sean
Post received from mailinglist |
|
|
| Back to top |
|
| tonyg |
Posted: Sun Jun 01, 2008 10:06 am |
|
|
|
User
Joined: 07 Nov 2006
Posts: 199
|
Hi Sean,
Sean Treadway wrote:
> Attached are 2 patches from my findings on how to expose some of the
> method parameters as STOMP headers. They include the following changes:
Thanks very much for these. They look good. I'll apply them.
> * expose 'passive', 'durable', 'auto-delete', 'exclusive' parameters of
> the AMQP 'queue.declare' method as STOMP headers in SUBSCRIBE
Hmm, naming and interoperability. While we're still in "experimental"
status we can use any names we like, of course, but I'd be interested to
compare and contrast the names we choose for things like this with the
names other STOMP-supporting brokers use for similar features.
Does anyone on the list have any comments around this area?
On a related note, what do you think about trying to more generally
expose more of the AMQP functionality over STOMP? We could look at ways
of using the AMQP protocol definition to autogenerate the necessary
marshalling code, just as we do for other transport and protocol bindings.
> I also found a bug in message persistence over server restarts in
> rabbitmq-1.3.0.
Well spotted. As you mention, this doesn't affect the core broker, or
any AMQP-speaking clients; it's limited to other transports. Your patch
will no doubt make life easier for future other-transport writers
> Big thanks to you all at LShift for building this beautiful code.
You're welcome! I take it you're using Ruby to interact with the broker
- have you tried any of the available Ruby AMQP clients out there? Can
you share with us what kind of thing you're doing with RabbitMQ?
> Points I am unsure about are - the role
> of the 'passive' parameter to queue.declare,
"passive" essentially checks that the queue exists without creating it.
If it doesn't exist, an error is signalled. I'll check to make sure the
behaviour of the STOMP adapter in this case is sensible.
> whether or not to expose
> the 'nowait' parameter,
Probably best not. Well, not until we run into a case where it's needed,
anyway - it's a bit of a nasty hack to work around the lack of
pipelining in AMQP.
> whether or not to try and match ActiveMQ's STOMP
> header names or stick with the AMQP naming,
This is a great question. I'd love to hear your thoughts on the subject,
not being familiar myself with any other broker-specific options and
headers.
> interoperability of the
> properties patch for brokers such as HTTP and regression of the
> properties patch against AMQP messages with binary properties.
It seems safe to me, since less information is discarded after your
patch than before.
> Also,
> the STOMP spec gives no insight for queue deletion when a durable queue
> is no longer needed. Any ideas for that one?
Good point. I think we're probably pretty free to implement extensions
of our own in this area - how about a "DELETE" command? This touches on
my question above of how best to expose more of AMQP.
Thanks again for the contribution,
Tony
_______________________________________________
rabbitmq-discuss mailing list
rabbitmq-discuss@lists.rabbitmq.com
http://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
Post received from mailinglist |
|
|
| Back to top |
|
| tonyg |
Posted: Sun Jun 01, 2008 9:28 pm |
|
|
|
User
Joined: 07 Nov 2006
Posts: 199
|
Hi again Sean,
Tony Garnock-Jones wrote:
> Thanks very much for these. They look good. I'll apply them.
The changes to the core broker will appear as part of the next broker
release. You'll probably have to maintain your patch manually until then.
The changes to the STOMP adapter have been applied and are currently
live on http://hg.opensource.lshift.net/rabbitmq-stomp/.
> "passive" essentially checks that the queue exists without creating it.
> If it doesn't exist, an error is signalled. I'll check to make sure the
> behaviour of the STOMP adapter in this case is sensible.
I ran a couple of tests to make sure that this was working properly, and
sure enough there were some problems, which I've now fixed as part of
http://hg.opensource.lshift.net/rabbitmq-stomp/rev/19b67fadda0d.
By the way, is it just me, or does the Ruby STOMP adapter get very
confused when the socket closes underneath it? I see fairly consistent
behaviour of 100% CPU usage, with the Ruby program just spinning, if the
socket's closed by the server for whatever reason. Odd!
Please let me know how the new tip works for you, if you try it out, Sean!
Thanks,
Tony
_______________________________________________
rabbitmq-discuss mailing list
rabbitmq-discuss@lists.rabbitmq.com
http://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Mon Jun 02, 2008 11:18 am |
|
|
|
Guest
|
Hi Tony,
Thanks for applying the patch! I see you caught that commented line
in the ruby receiver example - thanks.
On Jun 1, 2008, at 12: 05, Tony Garnock-Jones wrote:
>> * expose 'passive', 'durable', 'auto-delete', 'exclusive'
>> parameters of the AMQP 'queue.declare' method as STOMP headers in
>> SUBSCRIBE
>
> Hmm, naming and interoperability. While we're still in
> "experimental" status we can use any names we like, of course, but
> I'd be interested to compare and contrast the names we choose for
> things like this with the names other STOMP-supporting brokers use
> for similar features.
>
> Does anyone on the list have any comments around this area?
>
> On a related note, what do you think about trying to more generally
> expose more of the AMQP functionality over STOMP? We could look at
> ways of using the AMQP protocol definition to autogenerate the
> necessary marshalling code, just as we do for other transport and
> protocol bindings.
I chose the AMQP naming for this patch because I used the AMQP
documentation to learn/understanding the intended behavior of queue
declaration. I took a quick trip over to ActiveMQ's documentation
pages and saw that they had similar configuration with their own/
different naming but I consciously thought "This is not ActiveMQ, this
is RabbitMQ. I want to know that to leverage RabbitMQ features".
STOMP looked like it was MQ agnostic and extensible while keeping the
core headers well defined (ack=client, message_id, etc...), but my
application was not MQ agnostic. Plus I saw some of the ActiveMQ
headers weren't available or necessary in RabbitMQ.
Keeping the AMQP naming is the best way to piggy back on the AMQP
documentation. For those that need simple, transient queues, the
existing STOMP documentation would be sufficient.
>> Big thanks to you all at LShift for building this beautiful code.
>
> You're welcome! I take it you're using Ruby to interact with the
> broker - have you tried any of the available Ruby AMQP clients out
> there? Can you share with us what kind of thing you're doing with
> RabbitMQ?
We're using RabbitMQ as a job dispatcher for our media transcoder
machines and for our 1-many notification broadcasts (upload a track,
your fans are notified).
We chose RabbitMQ because after reading Joe's book on Erlang, OTP
quickly became the best choice for meeting the requirements of fail-
tolerance and scalability. Pure throughput wasn't an issue for us.
I've been keeping an eye on RabbitMQ for about a year, and have to
admit that the language tone and 'heaviness' around AMQP kept me from
adopting it in a previous project. The tone of rabbitmq.com was much
more accessible, so I had faith that this was an open source project
with dedicated maintainers so I put it on top of my list of MQ
candidates when I needed the reliability and could invest in this part
of our infrastructure.
I remember reading somewhere long ago that ruby AMQP lib was
incomplete and not very stable. The ruby source seemed complicated
and did much more than what we needed. AMQP solves a lot of problems,
most of which I am unfamiliar with.
When the STOMP broker was released I thought "great! STOMP looks just
like HTTP". I grabbed the ruby lib, understood it, and thought that
if anything went wrong, I could fix it. With RSS and XMPP experience,
it was easy for me to see how the publish-subscribe model we needed
was implemented in STOMP.
If we need anything more complicated like setting up custom exchanges
or finer control over routing, we'll probably switch to AMQP.
>> whether or not to try and match ActiveMQ's STOMP header names or
>> stick with the AMQP naming,
>
> This is a great question. I'd love to hear your thoughts on the
> subject, not being familiar myself with any other broker-specific
> options and headers.
I only have experience with RabbitMQ, so I'm fine with exposing AMQP
rather than try to come to some agreement over the extension names of
standard STOMP headers. Since I'm new around here, don't really know
the relationship between the RabbitMQ and ActiveMQ communities. If
we're all in this together and have good communication, it may be
worth the effort to harmonize on the naming. "What does consisting
naming across broker vendors give the consumers of our MQ" may be the
right question to ask.
>> Also, the STOMP spec gives no insight for queue deletion when a
>> durable queue is no longer needed. Any ideas for that one?
>
> Good point. I think we're probably pretty free to implement
> extensions of our own in this area - how about a "DELETE" command?
> This touches on my question above of how best to expose more of AMQP.
Here, I would stick with the verbs defined in STOMP and extend the
verbs with headers. One possibility is to use UNSUBSCRIBE messages to
change the queue properties before sending the 'basic.cancel' method.
Another possibility is to change queue properties on a SUBSCRIBE
message. Neither seem nice to me. Third option is to do nothing, and
delete the queues outside of the STOMP protocol (we're fine with that
as we have a fixed number of persistent queues).
How are auto-delete=false queues removed with AMQP?
On Jun 1, 2008, at 23: 28, Tony Garnock-Jones wrote:
> By the way, is it just me, or does the Ruby STOMP adapter get very
> confused when the socket closes underneath it? I see fairly
> consistent behaviour of 100% CPU usage, with the Ruby program just
> spinning, if the socket's closed by the server for whatever reason.
> Odd!
This was in the example's receive loop and not in the library itself,
the 'nil' message on socket closure was just being ignored. Here's a
receive loop that actually terminates . It could also be applied to
cb-receiver.rb:
while msg = conn.receive
puts msg.body
end
-Sean
_______________________________________________
rabbitmq-discuss mailing list
rabbitmq-discuss@lists.rabbitmq.com
http://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
Post received from mailinglist |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|