jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: (JMS_SPEC-40) Allow multiple threads in same client to consume messages from the same topic subscription

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Tue, 10 Apr 2012 16:11:23 +0100

I've had one comment on this from a colleague within Oracle, which is to suggest that we should make a small change to
the way that non-durable subscriptions are made available for use by multiple consumers. I proposed that for a
NON-durable subscription to be used by multiple consumers, each consumer must specify the same "sharedSubscriptionName".
My colleague suggested that if clientID was set we should use the tuple {ClientID, sharedSubscriptionName) to define the
subscription, for consistency with durable subscriptions.

My feeling is that this is probably not necessary. Because clientID is unique, setting clientID actually prevents the
use of a non-durable subscription by multiple consumers (except for the special case where those consumers use the same
connection). So there is no benefit in setting it.

Any comments?

Nigel

On 03/04/2012 15:57, Nigel Deakin wrote:
> I'd like to return to this issue, which we last discussed back in August last year:
> On 05/08/2011 15:37, Nigel Deakin wrote:
>> I have logged this JIRA issue:
>> http://java.net/jira/browse/JMS_SPEC-40
>
> I made some detailed proposals at the time, which seemed to be acceptable to this group, though I didn't have time to
> take these forward and add them to the Early Draft. I've reviewed these proposals and updated them to reflect the
> current state of the simplified API.
>
> Here's the current proposal. To see a formatted version which is somewhat easier to read, please see the JIRA issue. Any
> further comments? Do the JMS implementers on this group see any issues with this that I may have missed?
>
> Description
> ===========
>
> 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.
>
> Durable subscriptions
> ---------------------
>
> 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):
>
> createDurableSubscriber(Topic topic, String name)
> createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal)
>
> 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 (http://java.net/jira/browse/JMS_SPEC-51):
>
> createDurableConsumer(Topic topic, String name)
> createDurableConsumer(Topic topic, String name, String messageSelector, boolean noLocal)
>
>
> And in the new JMS 2.0 simplified API, it also affects the following method on JMSContext:
>
> createDurableConsumer(Topic topic, String name)
> createDurableConsumer(Topic topic, String name, String messageSelector, boolean noLocal)
>
> 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 4.4.3.2 "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
> (http://java.net/jira/browse/JMS_SPEC-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).
>
> Non-durable subscriptions
> -------------------------
>
> 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:
>
> MessageConsumer createSharedConsumer(
> Topic topic, String sharedSubscriptionName);
> MessageConsumer createSharedConsumer(
> Destination destination, String sharedSubscriptionName, String messageSelector)
> MessageConsumer createSharedConsumer(
> Destination destination, String sharedSubscriptionName, String messageSelector, boolean NoLocal)
>
> 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:
>
> JMSConsumer createSharedConsumer(
> Topic topic, String sharedSubscriptionName)
> JMSConsumer createSharedConsumer(
> Topic topic, String sharedSubscriptionName, String messageSelector)
> JMSConsumer createSharedConsumer(
> Topic topic, String sharedSubscriptionName, String messageSelector, boolean noLocal)
>
> Note that a given shared subscription does not exist if there are no consumers using it.