[ISSUE #10756] Fix duplicate dispatch ConsumeQueueExt leak - #10759
[ISSUE #10756] Fix duplicate dispatch ConsumeQueueExt leak#10759ai-yang wants to merge 1 commit into
Conversation
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Prevents ConsumeQueueExt orphan entries when duplicate dispatch requests arrive by extracting isDispatchAlreadyApplied() and applying it consistently in both the ext-write guard and the main dispatch path.
Findings
- [Info]
ConsumeQueue.java:730— The newisDispatchAlreadyApplied()extraction is clean and ensures bothputMessagePositionInfoWrapperandputMessagePositionInfouse the same duplicate check. Good consolidation. - [Info]
ConsumeQueue.java:901— The helper method is well-named and the semantics are clear (offset + size <= maxPhysicOffsetmeans the dispatch was already applied). - [Info]
ConsumeQueueTest.java— TesttestDuplicateDispatchDoesNotLeaveConsumeQueueExtOrphandirectly verifies the fix scenario with ext address validation after reload. Solid coverage.
Suggestions
- Consider adding a brief Javadoc on
isDispatchAlreadyApplied()explaining that it detects duplicate dispatch after broker crash recovery, to help future readers understand why the check matters in both call sites.
Automated review by github-manager-bot
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Summary
Fix for ConsumeQueueExt orphan entries during duplicate dispatch — extracts isDispatchAlreadyApplied() for consistent use in both the ext-write guard and the main dispatch path. Test coverage is solid.
The previous suggestion about Javadoc was informational only. The code is correct and the fix is well-targeted. LGTM.
Automated review by github-manager-bot
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Summary
Defensive fix with proper validation and test coverage. LGTM.
Automated review by github-manager-bot
|
@RongtongJin @guyinyou, could you please take a human review when convenient? This is a focused Store/ConsumeQueueExt fix that prevents duplicate dispatch from allocating an orphan Ext unit. The regression reproduces the old behavior deterministically; the complete Store reactor, Checkstyle, and SpotBugs pass. The remaining GitHub Actions runs are currently awaiting maintainer approval. |
586d998 to
d623f0d
Compare
|
Refreshed this PR against the latest
The force-push has retriggered the full CI matrix. |
|
CI triage update: The two failing checks are outside this PRs changed Store/ConsumeQueue path:
The affected |
Signed-off-by: Rui <1685901819@qq.com>
d623f0d to
f9247d2
Compare
|
Refreshed onto The rebase retains upstream #10566's mapped-file Clean JDK 8 verification: mvn -pl store -am -DskipITs -Dtest=ConsumeQueueTest,ConsumeQueueExtTest \
-Dsurefire.failIfNoSpecifiedTests=false clean test24 tests passed: This push starts fresh CI against the current base; the earlier Timer/LitePull failures are historical results, not validation of this refreshed head. @guyinyou @xdkxlk, could you review the early idempotency check and its interaction with CQ/Ext dispatch when convenient? |
|
New-head CI triage for
This points to the priority-consumption integration path, but it does not by itself establish a flaky test or exclude interaction with this change: the integration fixture enables ConsumeQueueExt. The full stdout was omitted from the job log because it exceeded the output-size limit, so the available XML only establishes the assertion above. I attempted to rerun the Bazel workflow, but GitHub rejected the author-side request with |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #10759 +/- ##
=============================================
- Coverage 49.36% 49.29% -0.08%
+ Complexity 14230 14216 -14
=============================================
Files 1390 1390
Lines 103123 103124 +1
Branches 13484 13484
=============================================
- Hits 50904 50831 -73
- Misses 46061 46117 +56
- Partials 6158 6176 +18 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Which Issue(s) This PR Fixes
Fixes #10756
Brief Description
ConsumeQueue.putMessagePositionInfoWrapper()allocated aConsumeQueueExtunit before the main CQ idempotency check. Replaying a duplicate dispatch therefore skipped the CQ append but still left an unreferenced Ext unit, which a later valid dispatch could seal inside the live Ext range.This change reuses the main CQ physical-end idempotency predicate before allocating an Ext unit. Duplicate replay still follows the existing successful wrapper path, so checkpoint advancement and multi-dispatch behavior are preserved while the orphan allocation is avoided.
How Did You Test This Change?
develop: the deterministic duplicate-dispatch regression failed in 5/5 isolated JDK 8 Maven processes.ConsumeQueueTest: 11/11.store -am test: common 241/241, remoting 174/174, and store 314 tests with 4 skips, 0 failures, and 0 errors.git diff --check: passed.Scope and Concurrency
The new guard reuses the physical-end idempotency predicate already applied by
putMessagePositionInfo()on the same dispatch attempt. It introduces no new shared state or locking and leaves supported writes, checkpoint advancement, retries, and multi-dispatch handling unchanged. This PR is scoped to duplicate re-dispatch; cleanup after a genuine Ext-append/CQ-append failure remains a separate failure mode.Applicability and user-visible impact
enableConsumeQueueExtdefaults tofalse. The affected path requires CQExt writes and duplicate Broker dispatch/recovery of an already-indexed physical message. This is internal index-build idempotency, not producer retry deduplication or an exactly-once delivery feature.The demonstrated impact is unreferenced extension allocation and extra storage retained in the live Ext range. It is not evidence of lost message bodies or permanent retention under every cleanup policy. Total disk cost and eventual reclamation depend on duplicate volume, mapped-file boundaries and normal retention cleanup; no production byte estimate or occurrence rate is claimed.