Working on
https://jira.jboss.org/jira/browse/JBMESSAGING-1505 about delivery optimization
for consumers with selectors.
The idea of the optimization is to provide to consumers with selectors their own iterators
on the queue so that they don't have to rescan the whole queue to find messages which
they can handle (when the filter match the message)
This means that:
- consumers with filters have an associated iterator that is used when the queue deliver
messages
- consumers without filters will peek the messages from the queue
In order to distinguish between the 2 types of consumers, we need to peek the consumer
which will handle the message from the distributor. I added a peekConsumer() to the
Distributor interface to be able to do that.
This works fine for RoundRobinDistributor but it is broken for
GroupingRoundRobinDistributor (in that case, it must know the message to determine which
consumer will handle it).
As message groups and queues with selectors are not compatible, there are several
options:
1/ forbids to use consumers with filters on a queue with message groups
2/ degrades the delivery algorithm in case of message groups with consumers with filters.
In that case, the current algorithm is used (with a full scan of the queue for each call
to deliver) (+ warning log)
I think (2) is a better option: this will give us the optimization in the most common case
and handles the anti pattern case with a degradation of performance.
The only real con is that this means we maintain 2 delivery algorithm:
- an optimized one (round robin distribution)
- an degraded one (messages groups distribution + consumers with filters)
depending on the distribution policy type, when QueueImpl.deliver() is called we either
use the deliverWithFullScan() (aka the current deliver algorithm) in the grouping
distribution case or
deliverWithIterators() in the round robin case
Some remarks on the new optimized algorithm:
* when a consumer with filter has finished iterating on the queue, I reassigned to it a
new messageReferences.iterator() so that it can handle new messages.
However this means it will iterate again on all the messages it has already discarded to
reach the new messages
* in the case of consumers without filters, I peek directly from the messageReferences
list to deliver. There is no need to have an iterator to share between all the consumers
without filters
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4241119#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...