Skip to content
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

Add preserveDeliveryMode to deadLetterStrategy #1354

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

pa-deasy
Copy link
Contributor

@pa-deasy pa-deasy commented Nov 15, 2024

What problems does this PR solve?
By default non persistent messages are set to persistent when being sent to a dead letter queue. This improvement adds preserveDeliveryMode to deadLetterStrategy which allows the original non-persistent delivery mode to be preserved.

Why is it beneficial to merge into ActiveMQ?
Users are able to take advantage of using non persistent messages on a dead letter queue.

How do you make sure this PR is well tested?
I ran the following tests locally on a build of this branch.

Test A

  • Created a queue deadLetterStrategy to process non persistent messages.
<policyEntry queue=">">
  <deadLetterStrategy>
     <sharedDeadLetterStrategy processNonPersistent="true" />
   </deadLetterStrategy>
</policyEntry>
  • Used a client to send a persistent message a queue, rolling back the session and causing the message to be redirected to a DLQ.
  • Verified via the web console that the DLQ message had Persistence set to Persistent.

Test B

  • Use the same deadLetterStrategy from Test A.
  • Used a client to send a non persistent message a queue, rolling back the session and causing the message to be redirected to a DLQ.
  • Verified via the web console that the DLQ message had Persistence set to Persistent and originalDeliveryMode set to NON_PERSISTENT.

Test C

  • Updated the queue deadLetterStrategy to preserve the delivery mode.
<policyEntry queue=">">
  <deadLetterStrategy>
     <sharedDeadLetterStrategy processNonPersistent="true" preserveDeliveryMode="true" />
   </deadLetterStrategy>
</policyEntry>
  • Used a client to send a non persistent message a queue, rolling back the session and causing the message to be redirected to a DLQ.
  • Verified via the web console that the DLQ message had Persistence set to Non Persistent.

@@ -60,6 +71,16 @@ public interface DeadLetterStrategy {
*/
public void setProcessNonPersistent(boolean processNonPersistent);

/**
* @return the PreserveDeliveryMode
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment needs to be updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@return the PreserveDeliveryMode

This is a new method which does return PreserveDeliveryMode. What exactly would you like to update?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I guess just the name is a bit confusing to me. Because it starts with "is" and return a boolean, if it returns the PreserveDeliveryMode it should be "get" imo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I noticed the "is" style is used for boolean methods in a number of places so I chose to be consistent.

Copy link

@Nikita-Shupletsov Nikita-Shupletsov Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, is for boolean is the convention

@kenliao94
Copy link
Contributor

@pa-deasy I assume the code that actually calls "setPreserveDeliveryMode" which is read from destination configuration will come later?

@kenliao94
Copy link
Contributor

kenliao94 commented Nov 24, 2024

I sort of see the points of moving the code to AbstractDeadLetterStrategy#prepareMessageForDeadLetterQueuefor readability in the chunky RegionBroker. My concern of that approach is that it effectively shifts the responsibility of preparing the message (setting correct attributes of the message object) to the this abstract class, which imo shouldn't need to be concern of it. This preparation is necessary before you send the message, but by moving to the strategy class, it feels like it's more a "util" then a necessary step. Furthermore, DeadLetterStrategy should have logic that only perform mutable action on the policy itself and shouldn't perform mutable actions on the Message object.

Hence I vote -1 on "move dead letter queue message preparation logic to the AbstractDeadLetterStrategy class" part of this PR. The getter and setter of perserveDeliveryMode on the Strategy class makes sense to me.

@mattrpav
Copy link
Contributor

I'm not in favor of refactoring RegionBroker in a point release. Ultimately, the DeadLetterStrategy should re-use the MessageInterceptorStrategy interface to it so admins can configure or change anything about the message on the way to the DLQ. All these one-off config params and methods creates bloat and all this logic should be pushed off into a handler.

@pa-deasy
Copy link
Contributor Author

@pa-deasy I assume the code that actually calls "setPreserveDeliveryMode" which is read from destination configuration will come later?
Yes that should be straightforward. I just wanted feedback on the RegionBroker and DeadLetterStrategy` for the draft.

Thanks folks for your feedback on "move dead letter queue message preparation logic to the AbstractDeadLetterStrategy class". Those are great points. I will update my PR appropriately and add tests.

Thank you.

@pa-deasy pa-deasy force-pushed the AMQ-7397-dlq-delivery-mode branch from 36ba737 to 7e810c4 Compare December 3, 2024 23:43
@pa-deasy pa-deasy changed the title [WIP] Add preserveDeliveryMode to deadLetterStrategy Add preserveDeliveryMode to deadLetterStrategy Dec 3, 2024
@pa-deasy pa-deasy force-pushed the AMQ-7397-dlq-delivery-mode branch from 7e810c4 to 05facc8 Compare December 4, 2024 00:16
@pa-deasy pa-deasy requested a review from kenliao94 December 4, 2024 00:20
@pa-deasy pa-deasy force-pushed the AMQ-7397-dlq-delivery-mode branch from 05facc8 to 92ac5e2 Compare December 4, 2024 00:35
/**
* @param PreserveDeliveryMode the PreserveDeliveryMode to set
*/
public void setPreserveDeliveryMode(boolean PreserveDeliveryMode);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preserveDeliveryMode

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good spot, not sure how I made this mistake.

@@ -60,6 +71,16 @@ public interface DeadLetterStrategy {
*/
public void setProcessNonPersistent(boolean processNonPersistent);

/**
* @return the PreserveDeliveryMode
Copy link

@Nikita-Shupletsov Nikita-Shupletsov Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, is for boolean is the convention

AMQ-7397 Move Message preparation back to RegionBroker.

AMQ-7397 Add message persistence tests for dead letter strategy.
@pa-deasy pa-deasy force-pushed the AMQ-7397-dlq-delivery-mode branch from 92ac5e2 to 4d1160e Compare December 4, 2024 17:19
message.setProperty(ActiveMQMessage.DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY,
poisonCause.toString());
}
message = prepareMessageForDeadLetterQueue(message, deadLetterStrategy, poisonCause);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need/should create a new method here. This method is only used one time so I don't see the benefit of refactoring this unless you are planning to call prepareMessageForDeadLetterQueue() in more than one spot or make it protected/package scope to override it or be accessible in tests so I would just leave things inline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought refactoring out made the prepareMessageForDeadLetterQueue method made the sendToDeadLetterQueue method easier to read and understand.
If folks don't agree I can revert the change?

Copy link
Contributor

@cshannon cshannon Dec 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, while the method is in fact descriptive about what it is doing, it actually makes it harder to understand what you changed because by copying it all to a new method it's not clear what exactly the difference is from the old code. You have to look at it carefully as the entire method shows up as a new change which is the biggest reason why I made the comment because i as staring at it for a while to even figure out what was different.

That being said it's not the biggest deal obviously, the compiler may end up inlining the method anyways.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, I've removed the prepareMessageForDeadLetterQueue method.

@@ -91,6 +129,14 @@ public void setProcessNonPersistent(boolean processNonPersistent) {
this.processNonPersistent = processNonPersistent;
}

@Override
public boolean isPreserveDeliveryMode() { return this.preserveDeliveryMode; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should have the same format as other getter for consistency. So return at new new line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange, my IDE(ItelliJ) made the other getters in AbstractDeadLetterStrategy appear to be single line.
I'll update this.

@cshannon
Copy link
Contributor

cshannon commented Dec 9, 2024

@mattrpav - Do you have any issues with the changes here? It seems ok to me, it preserves the previous behavior by default and I could see a use case for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants