Description of problem: There is a defined standard amqp1.0 property: first-acquirer. The broker shall support setting this property accordingly. If this value is true, then this message has not been acquired by any other link. If this value is false, then this message MAY have previously been acquired by another link or links. Version-Release number of selected component (if applicable): qpid-cpp-*-0.22-33 How reproducible: 100% Steps to Reproduce: n/a Actual results: first-acquirer property is not set by the broker Expected results: first-acquirer property is set by the broker Additional info:
Created attachment 863747 [details] Reproducer Reproducer program. To compile: g++ -lqpidclient -lqpidcommon -lqpidmessaging -lqpidtypes acquire_message_and_disconnect.cpp -o acquire_message_and_disconnect To run: service qpidd restart ./acquire_message_and_disconnect The program: - sends a message to address "q; {create:always}" (or to 1st program argument) - acquires the message from the queue q - disconnects from the broker - acquires and disconnects again Actual results: Properties: {} Properties: {x-amqp-delivery-count:1} Expected results: Properties: {x-amqp-first-acquirer:True} Properties: {x-amqp-delivery-count:1}
Created attachment 863748 [details] Trivial patch proposal Until I miss something, the first acquirer of a message is the one who gets the message with delivery count = 0. So isFirstAcquirer() call should return "getDeliveryCount() == 0". (please let me provide a scenario when first-acquirer = (delivery-count != 0), if I am wrong)
(In reply to Pavel Moravec from comment #2) > Until I miss something, the first acquirer of a message is the one who gets > the message with delivery count = 0. So isFirstAcquirer() call should return > "getDeliveryCount() == 0". I would say it is the first consumer who gets the message with delivery count == 0. If an acquired message is released, its delivery count will be decremented (so may return to 0 if being released from the only delivery attempt), however - in my opinion - the first-acquirer flag should never be reset. So while a delivery count of 0 means the message has never been (even partially) 'processed' by an application, first-acquirer == true is an even stronger guarantee that this is the first time it is ever being acquired (and has never been released).
Committed to upstream as r1573546.
According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release): "The rejected outcome when applied to a message will cause the delivery-count to be incremented in the header of the rejected message" "The delivery-count of the header of the released message MUST NOT be incremented" The qpid::messaging api behaves exactly the opposite way: The delivery-count is increased when message is released. The delivery-count is not increased when message is rejected and first-acquirer field value remains set to true. Expected result: Delivery-count header field is increased when message is rejected. Delivery-count header field is not increased when message is released. Both the rejected and released message have first-acquirer header field set to false. So in fact, the reproducer expected results are wrong and shall be the following: Properties: {x-amqp-first-acquirer:True} Properties: {} I believe that is a bug, right? [1] http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-complete-v1.0.pdf
(In reply to Petr Matousek from comment #6) > According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release): > > "The rejected outcome when applied to a message will cause the > delivery-count to be incremented in the header of the rejected message" > "The delivery-count of the header of the released message MUST NOT be > incremented" > > The qpid::messaging api behaves exactly the opposite way: > The delivery-count is increased when message is released. > The delivery-count is not increased when message is rejected and > first-acquirer field value remains set to true. > > Expected result: > Delivery-count header field is increased when message is rejected. > Delivery-count header field is not increased when message is released. > Both the rejected and released message have first-acquirer header field set > to false. > > So in fact, the reproducer expected results are wrong and shall be the > following: > Properties: {x-amqp-first-acquirer:True} > Properties: {} The reproducer neither rejects nor releases the message. It is unacknowledged at the point the connection is closed, so I think the reproducer expected results as stated in comment #1 are correct. The Session::release() method will actually set the outcome as MODIFIED, since the application has seen the message. The RELEASED outcome is used for prefetched messages. This means that messages the application fetched then released will have the delivery count incremented, whereas those that were prefetched but released without being seen will not. That matches the 0-10 behaviour (with the set-redelivered flag on message release being true for explicit release and false for implicit release of prefetched messages). A rejected messages is removed from the queue entirely. It may be routed to the alternate-exchange, but in this case it has its delivery count reset on any new queue (delivery count is tracked per queue).
(In reply to Gordon Sim from comment #7) > (In reply to Petr Matousek from comment #6) > > According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release): > > > > "The rejected outcome when applied to a message will cause the > > delivery-count to be incremented in the header of the rejected message" > > "The delivery-count of the header of the released message MUST NOT be > > incremented" > > > > The qpid::messaging api behaves exactly the opposite way: > > The delivery-count is increased when message is released. > > The delivery-count is not increased when message is rejected and > > first-acquirer field value remains set to true. > > > > Expected result: > > Delivery-count header field is increased when message is rejected. > > Delivery-count header field is not increased when message is released. > > Both the rejected and released message have first-acquirer header field set > > to false. > > > > So in fact, the reproducer expected results are wrong and shall be the > > following: > > Properties: {x-amqp-first-acquirer:True} > > Properties: {} > > The reproducer neither rejects nor releases the message. It is > unacknowledged at the point the connection is closed, so I think the > reproducer expected results as stated in comment #1 are correct. Agreed, I thought that unacknowledged messages shall behaves the same way as released messages. > > The Session::release() method will actually set the outcome as MODIFIED, > since the application has seen the message. The RELEASED outcome is used for > prefetched messages. This means that messages the application fetched then > released will have the delivery count incremented, whereas those that were > prefetched but released without being seen will not. That matches the 0-10 > behaviour (with the set-redelivered flag on message release being true for > explicit release and false for implicit release of prefetched messages). Ok, I'd expected released outcome to be applied when message is released, thanks for explanation. > > A rejected messages is removed from the queue entirely. It may be routed to > the alternate-exchange, but in this case it has its delivery count reset on > any new queue (delivery count is tracked per queue). I didn't know about the fact that delivery count reset is done when routing to another node, ie.: alt-ex (I haven't found that in spec.). Again, thanks for explanation. So, it's also expected the first-acquirer is set to true on the rejected message that is routed to alternate-exchange? I wouldn't expect that in this case.
(In reply to Petr Matousek from comment #8) > (In reply to Gordon Sim from comment #7) > > (In reply to Petr Matousek from comment #6) > > > According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release): > > > > > > "The rejected outcome when applied to a message will cause the > > > delivery-count to be incremented in the header of the rejected message" > > > "The delivery-count of the header of the released message MUST NOT be > > > incremented" > > > > > > The qpid::messaging api behaves exactly the opposite way: > > > The delivery-count is increased when message is released. > > > The delivery-count is not increased when message is rejected and > > > first-acquirer field value remains set to true. > > > > > > Expected result: > > > Delivery-count header field is increased when message is rejected. > > > Delivery-count header field is not increased when message is released. > > > Both the rejected and released message have first-acquirer header field set > > > to false. > > > > > > So in fact, the reproducer expected results are wrong and shall be the > > > following: > > > Properties: {x-amqp-first-acquirer:True} > > > Properties: {} > > > > The reproducer neither rejects nor releases the message. It is > > unacknowledged at the point the connection is closed, so I think the > > reproducer expected results as stated in comment #1 are correct. > > Agreed, I thought that unacknowledged messages shall behaves the same way as > released messages. Yes, they do. The release() method on the API is just a way of immediately returning the message to the queue rather than waiting for the session to end. > > The Session::release() method will actually set the outcome as MODIFIED, > > since the application has seen the message. The RELEASED outcome is used for > > prefetched messages. This means that messages the application fetched then > > released will have the delivery count incremented, whereas those that were > > prefetched but released without being seen will not. That matches the 0-10 > > behaviour (with the set-redelivered flag on message release being true for > > explicit release and false for implicit release of prefetched messages). > > Ok, I'd expected released outcome to be applied when message is released, > thanks for explanation. Not an unreasonable expectation :-) > > A rejected messages is removed from the queue entirely. It may be routed to > > the alternate-exchange, but in this case it has its delivery count reset on > > any new queue (delivery count is tracked per queue). > > I didn't know about the fact that delivery count reset is done when routing > to another node, ie.: alt-ex (I haven't found that in spec.). Again, thanks > for explanation. So, it's also expected the first-acquirer is set to true on > the rejected message that is routed to alternate-exchange? I wouldn't expect > that in this case. It isn't explicitly covered in any spec from my reading. It is 'expected' in the sense that there is a explicit line in the code that resets the delivery count and the first-acquired flag. However this is only done for rejected message, not for messages rerouted for other reason (e.g. orphaned, or explicit qmf reroute request). I can't see any reason why reject should behave differently here. There is one test that fails when the reset is not done (qpid.tests.messaging.endpoints.SessionTests.testReject), and I suspect that the explicit reset was added just to avoid that failure. However on reflection, perhaps it is the test that is wrong there. I'd be happy to treat that as a bug, but probably simplest to treat it as a a distinct issue from this BZ. (It affects both 0-10 and 1.0)
The issue from comment 9 above is now tracked as bug 1183140.
AMQP 1.0 defined 'first acquirer' header is now accessible via 'x-amqp-first-acquirer' flag in the message properties map using qpid::messaging API. Verified on rhel6.6 (x86_64 and i386) Packages: qpid-cpp-*-0.30-5 -> VERIFIED
(In reply to Petr Matousek from comment #11) correction: Packages: qpid-cpp-*-0.30-5 (reproducible) -> qpid-cpp-*-0.30-6 (fixed)
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHEA-2015-0805.html