azure-sdk-for-java: Do not serve expired messages to the user
As reported in #25259, there is a chance for ServiceBusReceiverClient.receiveMessages()
to return expired messages to the user even when prefetch is disabled. One of the side effects of this is that the user gets such messages served one more time. This issue is logged after a discussion with @shankarsama to explore the option of the client dropping such expired messages to
- avoid serving duplicate messages to the user
- reduce the number of lock lost exceptions the user gets when they try to settle such messages
Update: The approach chosen is to release messages as soon as they are received by the client if there is no active receive call from the user. This will apply only when prefetch is disabled.
The check of whether a message is expired can be made by looking at the lockedUntil property on the message.
The potential downside of this approach is that a message might get dropped in such a manner multiple times reaching the max delivery count and get pushed to the dead letter queue without giving the user a chance to process it. This invalidates the at-least once promise. Therefore, it might be beneficial to add this feature behind an option and document that it is recommended to have a higher delivery count when using this option.
Adding @shankarsama and @yvgopal to provide any additional thoughts
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 17 (16 by maintainers)
Yes, this is why I’m being very explicit - there are two different models for this API. If you want to handle locking/dispatching in the client and allow parallel ReceiveMessages() calls then drain after each receive completes doesn’t really make sense. (ie, we are in agreement).
I don’t know which particular style Java has, but they might have choices in this matter depending on what they’ve already published as a guarantee.