12 Replies Latest reply on Aug 10, 2007 6:14 AM by Aslak Knutsen

    Grouping of messages with JMSXGroupId(JBMESSAGING-375)

    Stian Hegglund Newbie

      Hi, I'm trying to do my first contribution to JBoss Messaging so be nice :)
      I worked on a project last year where message groups (messages with the same group id always go to the same consumer on a queue).
      would have been really useful. I just finished a working proof of concept, which I hope to complete with help and feedback.

      To continue to support the default round robin routing when JMSXGroupID is not supplied, I modified the existing RoundRobinPointToPointRouter to route based on given JMSXGroupID when supplied.

      The Delivery handle(...) now behaves like this:
      get the reciver by round robin. if a groupId is given, try to see if a receiver is already assigned to handle this group.
      If it is, use this to deliver.
      Else bind the receiver given by round robin to the groupId in the message.
      deliver using this receiver.

      If the receiver is broken, remove the binding between the current receiver and the groupId.

      This approach will ensure that round robin works as before, and that each consumer will have an equal chance to be bound to spesific groups. If a receiver is broken, the mapping will be removed and a new receiver will be selected to handle the group.

      To support a large number of groups in an efficient way, I decided not to use some kind of map which grows for each new group that needs a mapping to a receiver.

      The current solution uses a large Receiver array. Ie. 1000 elements.

      Receiver[] receiverGroupMapping = new Receiver[1000];

      A mapping between a groupId and a receiver is then resolved by Math.abs(groupId.hashCode() % receiverGroupMapping.length).
      The returned number will be the position in the receiverGroupMapping to insert,get or remove a receiver from.

      The large array and usage of hashCode from the String should give a nice distribution of receivers for groupId's even when there are extremely large number of groups.

      In the spec, all that is mentioned about JMSXGroupId (see 3.5.9 JMS Defined Properties):

      "JMSXGroupID and JMSXGroupSeq are standard properties clients should use if they want to group messages. All providers must support them. "

      The actual semantics of the JMSXGroupSeq is not mentioned, so for now it is not used for anything.

      I don't know if this is how you want this implemented, but I hope it's at least enough to get a discussion started :).

      Inside the router I use ref.getMessage().getHeader("PJMSXGroupID") to get the groupId, since JMSXGroupID is a JMS spesific property
      it might be forbidden to know about this property inside core of messaging ?

      I have not explored if my changes breaks anything in a clustered environment etc.

      Stian Hegglund