-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: [AMQ-9554] Browsing a DLQ in transacted mode should allow redelivered messages #1286
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make sense to me and seems to hide the root issue. That method is simply checking if redelivery was already exceeded and handling it if it is. It also checks if the message has been expired. There's no reason to not discard the message on browse if redelivery was exceeded. Here is where expiration is also done in the same section where we discard on delivery exceeded:
activemq/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java
Line 510 in e45ee4a
} else if (consumeExpiredMessage(md)) { |
activemq/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java
Line 1432 in e45ee4a
boolean expired = isConsumerExpiryCheckEnabled() && message.isExpired(); |
And note we specifically check if we are a browser in this case:
activemq/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java
Line 1423 in e45ee4a
if (this.info.isBrowser() || md.getDeliverySequenceId() != 0l || !session.connection.isDuplicate(this, md.getMessage())) { |
Is the actual problem that browsing is incrementing the counter when dispatched to a browser and shouldn't be?
so re-reading what you wrote, you said it applies to a DLQ which would be an edge case but your change seems like it changes the behavior for every consumer and every queue and not just DLQs which we would not want. If the goal is to simply be able to browse the DLQ and preventing not being able to read messages that were previously exceeding the redelivery policy then for your DLQ consumer can you simply disable the redelivery policy? Seems like a simple solution. |
@cshannon the updated test has the full repro scenario. commit: a7df4ca The issue comes down to:
Currently, ActiveMQMessageConsumer does send a poison ack. The problem with that is it creates two messages, as the original stays on the source queue (dlq or otherwise) AND a message to a DLQ (or .DLQ.DLQ when browsing a .DLQ). My argument is that browser should not send a poison ack if the max redelivery count is reached. Note: This only occurs if QueueBrowser is created off of a transacted session. |
If you don't want to create the poison ack then couldn't you simply disable the redelivery policy when browsing the DLQ since it's an edge case? This seems like a client side config issue because you are setting that policy....so just don't set it when browsing the DLQ. Consumers (including browsers) are designed to process the messages and check things like the redelivery counter or even expiration. A browser should not increment the redelivery counter, but I don't see how checking that counter and sending a poison ack is any different than checking expiration and expiring a message which it will do. |
browser = browseSession.createBrowser(queueDLQ); | ||
Enumeration<?> enumeration = browser.getEnumeration(); | ||
while (enumeration.hasMoreElements()) { | ||
Message message = (Message)enumeration.nextElement(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BUG: This blocks indefinitely
Scenario:
- Message on the queue at the edge of maximumRedeliveries
- Browse in transacted mode
- Consumer code poison-acks the one message
- Browse thinks there are messages to enumerate over, but there are not
- nextElement blocks indefinitely waiting to get messages b/c no conditions are met to break out of the while(true) loop
Planned fix path forward:
|
Yes! With the caveat that it is only when browsing in a transacted session. In AUTO_ACK mode this behavior does not occur. |
Reproduce project: https://github.com/hyteio/hyte-activemq-redelivery-inconsistent
Summary:
Message with 7 JMSXRedeliveryCount (on the broker)
Proposed default behavior:
Queue Browser should be consistent regardless of ack mode when browsing messages and not send a poison ack based on redelivery policy.
Planned fix path forward: