This proposal would allow multiple message consumers to be used to consume messages from the same durable or non-durable topic subscription. This would increase scalability by allowing messages from a topic to be processed by multiple consumers in a Java SE environment. Note that the existing JMS 1.1 API already allows this to be achieved for messages from a queue.
The multiple consumers might be in the same or different JVMs. Within the same JVM, the multiple consumers might use the same or different sessions and connection. Note, however, that the normal restrictions on the use of a session by multiple threads would continue to apply.
For durable subscriptions, there would be no need to change the existing API. Applications would simply be allowed to create multiple consumers on the same durable subscription:
This affects the following JMS existing JMS 2.1 methods on Session (and its subtypes QueueSession, TopicSession, XASession, XAQueueSession and XATopicSession):
It also affects the following JMS new JMS 2.0 methods on Session (and its subtypes QueueSession, TopicSession, XASession, XAQueueSession and XATopicSession) (added in JIRA issue 51 ):
And in the new JMS 2.0 simplified API, it also affects the following method on JMSContext:
All these methods currently have a restriction "Only one session at a time can have a TopicSubscriber for a particular durable subscription.". This restriction would be removed.
No change is proposed to the existing JMS requirement that only one connection may have a given clientID. This is defined in JMS 1.1 Section 188.8.131.52 "Client identifier", which states:
By definition, the client state identified by a client identifier can be 'in use' by only one client at a time. A JMS provider must prevent concurrently executing clients from using it.
This means that if a durable subscription is created by a connection with clientId set then it will not be possible to create a second consumer on it using a different connection.
However in JMS 2.0, clientId will become optional when creating a durable subscription (see JIRA issue 39). If a durable subscription is created by a connection with clientId unset then other connections may freely create further consumers on the same durable subscription.
This means that for two message consumers on different connections to share a durable subscription, clientId would need to be left unset.
In addition, the effect of using a different topic or message selector than was used when the subscription was first created needs to be amended. Currently this states (from the javadoc for Session.createDurableSubscriber):
A client can change an existing durable subscription by creating a durable TopicSubscriber with the same name and a new topic and/or message selector. Changing a durable subscriber is equivalent to unsubscribing (deleting) the old one and creating a new one.
This behaviour will continue, but only if there are no other active consumers on the durable subscription. If there is an active consumer on the durable subscription, and an attempt is made to create an additional consumer with a different topic or message selector, then a JMSException will be thrown (in the case of JMSContext a JMSRuntimeException will be thrown).
The semantics for the unsubscribe methods on Session and JMSContext would remain unchanged. The javadocs state that "It is erroneous for a client to delete a durable subscription while there is an active MessageConsumer or TopicSubscriber for the subscription". This will continue to be the case.
For non-durable subscriptions, the JMS 1.1 specification specifies that if two non-durable TopicSubscribers are created on the same topic then two independent subscriptions are created: a copy of each message is sent to every consumer on that topic (with an appropriate message selector).
To allow two consumers to share the same subscription, so that they can share the load of processing messages from that subscription, then new API is required. To allow the consumers to specify that they wish to use the same non-durable subscription, they will need to specify the same sharedSubscriptionName.
The following new methods on Session (and its subtypes) are proposed:
Note that if these methods were called simply createConsumer there would be a clash with the existing method createConsumer(Destination destination, String messageSelector). Note that these methods take a Topic, not a Destination.
In the new simplified API, the following new methods on JMSContext are proposed:
Note that a given shared subscription does not exist if there are no consumers using it.