Bug 669454 - qpid::messaging::Session.isValid() returns true but any use of the session throws a qpid::messaing::SessionError after attempting to subscribe a second receiver to an exclusive queue
Summary: qpid::messaging::Session.isValid() returns true but any use of the session th...
Keywords:
Status: NEW
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: qpid-cpp
Version: 1.3
Hardware: x86_64
OS: Linux
low
medium
Target Milestone: ---
: ---
Assignee: messaging-bugs
QA Contact: MRG Quality Engineering
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-01-13 18:05 UTC by Isaac Betesh
Modified: 2020-11-04 18:29 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed:
Target Upstream Version:


Attachments (Terms of Use)

Description Isaac Betesh 2011-01-13 18:05:01 UTC
Description of problem:
If you create a second receiver on an exclusive queue, createReceiver() returns without throwing an exception.  isValid() returns true afterwards when it is called on the session and on the receivers.  However, any attempt to use the session (such as createSender()) or either receiver (such as fetch() or close()) throws a qpid::messaing::SessionError

How reproducible:
always

Steps to Reproduce:
1. Create a connection and a session (session1)
2. Create a topic exchange ("Test.Ex")
3. qpid::messaging::Receiver receiver1 = session1.createReceiver("TestQueue;{create:always, link:{x-bindings:[{exchange:Test.EX, key:TestBinding, queue:TestQueue}], x-subscribe:{exclusive:True}}, mode:consume, node:{type:queue, x-declare:{auto-delete:True}}}");
4. qpid::messaging::Receiver receiver2 = session1.createReceiver("TestQueue;{create:always, link:{x-bindings:[{exchange:Test.EX, key:TestBinding, queue:TestQueue}], x-subscribe:{exclusive:True}}, mode:consume, node:{type:queue, x-declare:{auto-delete:True}}}");
  
Actual results:
session1.isValid(); //returns true
receiver1.isValid(); //returns true
receiver2.isValid(); //returns true
receiver[1|2].[fetch|close] throws SessionError.
session.create[Sender|Receiver] throws SessionError.


Expected results:
createReceiver() should throw (preferably), or (if that is not possible due to other constraints), since the session cannot be used anymore, isValid() should return false afterwards.

Comment 1 Gordon Sim 2011-01-13 18:20:11 UTC
At present isValid() only refers to the validity of the handle/smart pointer. There is a separate method for checking whether the object it refers to (if it refers to any) is still error free and usable: hasError().

I accept this is a little ugly.

You say that the createSender() throws SessionError in the 'actual results', and in the 'expected results' then say 'createReceiver() should throw (preferably)'. I'm confused by that. Certainly I agree that it should throw; are you saying it does not at present?

Comment 2 Isaac Betesh 2011-01-13 18:41:18 UTC
I apologize for being unclear.  Expected results are that, subsequent to attempting to create the second receiver, additional calls to createReceiver (assuming they don't try to use the exclusive queue) should not throw because the first call should just fail but should not invalidate the session.

Actual results are that the call to createReceiver that attempts to create the second receiver invalidates the session, causing later calls to create[Receiver|Sender] to throw.

hasError() is certainly helpful, but it doesn't address the real issue: If you try to create a receiver and cannot do so because of an exclusivity conflict, it shouldn't invalidate the session, it should just fail to create the receiver.

Comment 3 Gordon Sim 2011-01-13 21:42:19 UTC
"hasError() is certainly helpful, but it doesn't address the real issue: If you
try to create a receiver and cannot do so because of an exclusivity conflict,
it shouldn't invalidate the session, it should just fail to create the
receiver."

The issue there is that the underlying AMQP 0-10 session is invalidated (the protocol specification states this). This means that for example any unacknowledged messages sent out to consumers on that session will be requeued for redelivery.

In short at present it is quite hard to make the underlying loss of the AMQP session transparent and at least leaving it invalid makes it clear that a new session needs to be created. This is an area that needs further thought however. I agree that as it is it is not ideal.

Comment 4 Isaac Betesh 2011-01-13 22:32:09 UTC
> The issue there is that the underlying AMQP 0-10 session is invalidated (the
> protocol specification states this).

So the spec requires the session to become invalid if an illegal action (i.e. subscribing an additional receiver to an exclusive queue) is attempted?  

If that's so, exclusivity does more harm than good--instead of protecting a consumer's privacy, it gives other consumers a way to continually invalidate the consumer's session.

Comment 5 Gordon Sim 2011-01-14 10:09:45 UTC
> So the spec requires the session to become invalid if an illegal action (i.e.
> subscribing an additional receiver to an exclusive queue) is attempted?  

Yes, in AMQP 0-10 (and earlier versions) any 'exception' renders the session invalid. Some error conditions will also render the connection invalid. The philosophy behind that decision is that exceptions/errors may leave the two peers uncertain about the conversation state and it is simplest/safest to reset. May sound good in theory, but can be inconvenient in practice and is unnecessarily harsh in many cases.

> If that's so, exclusivity does more harm than good--instead of protecting a
> consumer's privacy, it gives other consumers a way to continually invalidate
> the consumer's session.

Not really. If an exclusive subscription succeeds, that subscriber knows that only they can consume messages from the queue. If others attempt to subscribe, they will be unsuccessful. It's not intended to protect 'privacy' as such, it's intended to grant exclusive access for cases where it is important that there is only one consumer of messages (e.g. because all messages must be consumed by the same processing agent in the correct order).


Note You need to log in before you can comment on or make changes to this bug.