stomp
acechases-activemq-wildcard
Working on the support of wildcard queue names. more…
Existing Implementation
- A client requests a subscription to a particular queue and provides a code block with the subscription request.
- The code block takes a single “message” argument and is called when messages are received for the subscription.
- The code block takes a single “message” argument and is called when messages are received for the subscription.
- The Stomp::Client code converts the block provided with the subscription into a proc and puts that proc into a hash of “listeners” where the key for the hash is the name of the queue that the subscription was made against.
- When messages are then sent from the server to the client for that particular subscription, the listener is retrieved by using the value from message.headers[‘destination’] to index into the “listeners” hash.
For the normal case, this works perfectly fine. Example:
queue_name = "/queue/status/alerts"
client.subscribe(queue_name) {|message| logger.error(message.body) }
Attaching a trace to ActiveMQ’s stomp protocol, we can see messages coming across the wire looking like this:
2010-04-26 17:36:42,807 [127.0.0.1:56769] TRACE StompTransportFilter - Sending:
MESSAGE
content-type:text/plain; charset=UTF-8
message-id:ID:foobar-34020-1272301031369-2:1076:-1:1:1
destination:/queue/status/alerts
timestamp:1272328602806
expires:0
content-length:1
priority:0
When Things Fall Apart
The above implementation is all well and good for a vanilla messaging system, however it runs into problems when using ActiveMQ, which allows for the use of wildcarding in the names of queue subscriptions (http://activemq.apache.org/wildcards.html). Using wildcards in the subscription name means there no longer be a one-to-one correspondence between the queue name provided to the subscription and the destination name found in the message headers. In the current implementation of the Stomp client, when messages are received that have no known listener they are simply ignored (there is an “if” block that looks for a listener and if it doesn’t find the listener no “else” block is available).
Justification for a Fix
Is this just an ActiveMQ feature that a Stomp client should not be concerned with? I would like to argue that no, it is not. In particular, the documentation provided in the Stomp protocol specifically refers to the use of wildcards and selectors (from http://stomp.codehaus.org/Protocol):
You can also specify an id header which can then later on be used to UNSUBSCRIBE from the specific subscription as you may end up with overlapping subscriptions using selectors with the same destination. If an id header is supplied then Stomp brokers should append a subscription header to any MESSAGE commands which are sent to the client so that the client knows which subscription the message relates to. If using Wildcards and selectors this can help clients figure out what subscription caused the message to be created.
Proposed Solution
It would seem that there are two approaches that can be taken:
- Use subscription ids in all cases and always fetch the appropriate listener based on the received message’s “subscription” header.
- Upside: Very clean implementation; Should always work as expected; No ActiveMQ-specific information needed.
- Downside: Message weight is increased slightly due to the extra “subscription” header.
- Upside: Very clean implementation; Should always work as expected; No ActiveMQ-specific information needed.
- Regexp the subscription name and look for ActiveMQ wildcards in the name. If found, provide a subscription id to the server and use that subscription id to find the appropriate listener when it is provided with messages.
- Upside: Users who are not working with ActiveMQ wildcards (or selectors) will not have subscription ids being added to their communications.
- Downside: The logic for looking up the listener for a message will be branched to handle two different scenarios; Knowledge of ActiveMQ wildcarding will be embedded in the Stomp Client code.
- Upside: Users who are not working with ActiveMQ wildcards (or selectors) will not have subscription ids being added to their communications.
Unless someone can present a good argument against solution #1, I'm going to go ahead and patch with that approach in mind.
The solution I am working on is small in scope, it is limited to changing the way the hash lookup is done on the “listeners” hash. Before using a destination name into the “listeners” hash I first massage the name into a valid regular expression where references to “” and “>” (the two ActiveMQ wildcards) are converted to their regexp equivalents (\w+ and “.” respectively). Then, when looking for the listener callback for a given message we simply lookup the listener whose regexp matches the destination header.
-
Cloning this repository:
git clone git://gitorious.org/~acechase/stomp/acechases-activemq-wildcard.git acechases-activemq-wildcard cd acechases-activemq-wildcard
Add this repository as a remote to an existing local repository:
git remote add acechases-activemq-wildcard git://gitorious.org/~acechase/stomp/acechases-activemq-wildcard.git git fetch acechases-activemq-wildcard git checkout -b my-local-tracking-branch acechases-activemq-wildcard/master_or_other_branch
- Branches:
- master
- Clone of:
- mainline
Activities 
-
Wednesday April 28 2010
-
Repository
05:01
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
-
Tuesday April 27 2010
-
Push
17:48
-
Repository
16:56
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
Repository
16:55
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
Repository
16:54
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
Repository
16:53
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
Repository
16:52
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
Repository
16:51
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
Repository
15:58
acechase updated repository ~acechase/stomp/acechases-activemq-wildcard
Changed the repository description
-
-
Monday April 26 2010
-
Repository
17:57
acechase cloned stomp/mainline
New repository is in acechases-activemq-wildcard
-

