Skip to content

[ISSUE #11174] Restore receipt handles when proxy ACK fails - #11175

Open
zmuxuny wants to merge 1 commit into
apache:developfrom
zmuxuny:fix/proxy-ack-retry-receipt-handle
Open

zmuxuny wants to merge 1 commit into
apache:developfrom
zmuxuny:fix/proxy-ack-retry-receipt-handle

Conversation

@zmuxuny

@zmuxuny zmuxuny commented Sep 17, 2026

Copy link
Copy Markdown

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 makes ackMessage(...) return an already exceptionally-completed future. On the unmodified baseline, the request returns an internal error but verification fails because addReceiptHandle(...) is never invoked:

Wanted but not invoked:
messagingProcessor.addReceiptHandle(...)

The preceding 11 modules in the proxy -am reactor succeeded; only this regression failed.

How Did You Test This Change?

Focused coverage now includes:

  • exceptional single-message ACK restores the managed handle;
  • synchronously thrown ACK restores the managed handle;
  • exceptional batch ACK restores all removed managed handles;
  • successful ACK does not restore the mapping.

Final verification:

mvn -B -ntp -pl proxy -am -Dtest=AckMessageActivityTest -Dsurefire.failIfNoSpecifiedTests=false test

Result: 6 tests passed, 0 failures/errors/skips. All 12 modules in the proxy -am reactor completed successfully. Checkstyle reported 0 violations and SpotBugs 0 bug instances / 0 errors in every module where those checks run. git diff --check also passes.

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 because handleContexts is 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: ReceiptHandleContext fields are package-private; private final would be more encapsulated, but this is cosmetic.

LGTM.


Automated review by github-manager-bot

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.

[Bug] Restore managed receipt handles when gRPC ACK fails exceptionally

2 participants