Conversation
RockteMQ-AI
approved these changes
Sep 17, 2026
RockteMQ-AI
left a comment
Contributor
There was a problem hiding this comment.
Summary
This PR fixes a real correctness issue in the proxy ACK path: when the Broker ACK fails (async or sync), the receipt-handle mapping — which may contain a newer handle from automatic invisible-time renewal — was permanently lost, forcing the client to fall back to a stale handle on retry. The fix captures the ReceiptHandleContext before removal and restores it in both the whenComplete (async failure) and catch (sync throw) paths.
Observations
- Correctness: Both failure paths (async exceptional completion and synchronous throw) are covered. The restore iterates by index against
request.getEntries(i), which is safe becausehandleContextsis built in the same loop order. - Error isolation: Restore failures are caught and logged without propagating — correct, since we must not mask the original error.
- Tests: Four new tests cover all paths (async fail → restore, sync throw → restore, batch partial fail → restore, success → no restore). Good coverage.
- Minor style:
ReceiptHandleContextfields are package-private;private finalwould be more encapsulated, but this is cosmetic.
LGTM.
Automated review by github-manager-bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which Issue(s) This PR Fixes
Fixes #11174
Brief Description
The gRPC ACK path removes a proxy-managed receipt-handle mapping before the Broker ACK completes. That mapping can contain a newer receipt handle produced by automatic invisible-time renewal. If the subsequent ACK invocation throws or its future completes exceptionally, the mapping is lost and a client retry can fall back to its stale receipt handle.
This change keeps the existing remove-on-ACK behavior for normal Broker/business results, but restores the removed managed handle when the ACK attempt itself fails exceptionally or synchronously. The same protection is applied to batch ACK: mappings removed while preparing the batch are restored only when the batch invocation fails as a whole.
Fail-before evidence
Baseline:
develop@bc33e8e4d7b25089af5f51bc669bdfedabfebe7d.A deterministic regression makes
removeReceiptHandle(...)return a newer managed handle and then makesackMessage(...)return an already exceptionally-completed future. On the unmodified baseline, the request returns an internal error but verification fails becauseaddReceiptHandle(...)is never invoked:The preceding 11 modules in the
proxy -amreactor succeeded; only this regression failed.How Did You Test This Change?
Focused coverage now includes:
Final verification:
mvn -B -ntp -pl proxy -am -Dtest=AckMessageActivityTest -Dsurefire.failIfNoSpecifiedTests=false testResult: 6 tests passed, 0 failures/errors/skips. All 12 modules in the
proxy -amreactor completed successfully. Checkstyle reported 0 violations and SpotBugs 0 bug instances / 0 errors in every module where those checks run.git diff --checkalso passes.