Skip to content

fix: infinite loop in getBulkData, CME in PopReviveService, and NPEs in broker client code - #10732

Open
yyqdbngt wants to merge 1 commit into
apache:developfrom
yyqdbngt:fix/getbulkdata-loop-and-broker-cme-npe
Open

fix: infinite loop in getBulkData, CME in PopReviveService, and NPEs in broker client code#10732
yyqdbngt wants to merge 1 commit into
apache:developfrom
yyqdbngt:fix/getbulkdata-loop-and-broker-cme-npe

Conversation

@yyqdbngt

@yyqdbngt yyqdbngt commented Jul 31, 2026

Copy link
Copy Markdown

Motivation

Three bugs found by code review (verified against the current develop branch):

  1. CommitLog.getBulkData can loop forever (store/src/main/java/org/apache/rocketmq/store/CommitLog.java)
    When findMappedFileByOffset returns null (offset below the first mapped file or in a deleted-file gap), the loop body does nothing — neither remainSize nor startOffset advances and there is no else break. The calling thread (e.g. replication checksum) spins forever. Added a warning log and break.

  2. PopReviveService throws ConcurrentModificationException while committing offsets (broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java)
    The loop removed entries via inflightReviveRequestMap.remove(oldCK) while iterating the fail-fast TreeMap iterator, so two consecutive finished checkpoints threw CME and aborted the offset-commit loop, risking duplicate redelivery. Switched to iterator.remove().

  3. Broker2Client.getConsumeStatus NPE for offline groups (broker/src/main/java/org/apache/rocketmq/broker/client/net/Broker2Client.java)
    getConsumerGroupInfo(group) returns null when the group has no connected consumers; dereferencing it threw NPE on the GET_CONSUMER_STATUS admin RPC. Guarded the null case.

Verification

mvn -pl broker -am compile passes on the build server.

Diff

3 files changed, +12 / -4.

@yyqdbngt
yyqdbngt force-pushed the fix/getbulkdata-loop-and-broker-cme-npe branch from 5f8def9 to cf84703 Compare July 31, 2026 15:23

@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.

Review by github-manager-bot

Summary

Three targeted bug fixes in broker and store modules: infinite loop in CommitLog.getBulkData, ConcurrentModificationException in PopReviveService, and NPE in Broker2Client.getConsumeStatus. All three are legitimate defects found by code inspection, and the fixes are minimal and correct.

Findings

  • [Info] CommitLog.java — The else break with a warning log is the right call for the null-mapped-file case. Consider adding the offending startOffset value to the log message (e.g. log.warn("... startOffset={}", startOffset)) to aid debugging if this path is ever hit in production.

  • [Info] PopReviveService.java — Switching from map.remove() to iterator.remove() is the textbook fix for CME on a TreeMap. The comment explaining the rationale is helpful. No issues.

  • [Info] Broker2Client.java — The null guard on getConsumerGroupInfo(group) is correct. The existing null == channelInfoTable || channelInfoTable.isEmpty() check on line 257 already handles the null case gracefully by returning SYSTEM_ERROR with a descriptive remark. Clean fix.

Verdict

All three fixes are well-scoped, correct, and improve broker stability. LGTM.


Automated review by github-manager-bot

…n Broker2Client

- CommitLog.getBulkData: when findMappedFileByOffset returns null the loop
  body does nothing, so remainSize/startOffset never advance and the thread
  spins forever; break out with a warning log instead
- PopReviveService: removed entries from the fail-fast TreeMap-backed map via
  map.remove() while iterating, throwing ConcurrentModificationException and
  aborting offset commits; use the iterator's remove()
- Broker2Client.getConsumeStatus: getConsumerGroupInfo(group) is null when the
  group is not online, dereferencing it throws NPE; guard it

Compiled and verified on the build server (mvn -pl broker -am compile).
@yyqdbngt
yyqdbngt force-pushed the fix/getbulkdata-loop-and-broker-cme-npe branch from cf84703 to e30b59b Compare July 31, 2026 15:34

@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.

Review by github-manager-bot

Summary

This PR fixes three critical bugs in broker code: NPE in Broker2Client, CME in PopReviveService, and infinite loop in CommitLog.getBulkData.

Findings

[Positive] Broker2Client.java:253-256 — NPE fix is correct. Extracting consumerGroupInfo to a local variable and adding null check prevents NPE when the consumer group doesn't exist yet. The existing null check on channelInfoTable handles the null case properly.

[Positive] PopReviveService.java:593-608 — CME fix is correct. Using iterator.remove() instead of map.remove() during iteration is the proper way to avoid ConcurrentModificationException on fail-fast collections. The comment explains the rationale well.

[Positive] CommitLog.java (getBulkData) — Infinite loop fix is correct. Adding break when mappedBufferResult is null prevents the loop from running forever when the mapped file can't be found. This is a critical stability fix.

[Info] ServiceThreadTest.java:164-168 — Widening the timeout thresholds (20ms→2000ms, 18ms→1000ms) makes the test more resilient to CI scheduler jitter. The comment explains the reasoning well.

Suggestions

  • Consider adding a unit test for the getBulkData infinite loop scenario to prevent regression.

Overall

All three bug fixes are correct and follow best practices. The code is clean and well-documented.


Automated review by github-manager-bot

@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.

Review by github-manager-bot

Summary

Fixes three critical bugs: infinite loop in CommitLog.getBulkData(), ConcurrentModificationException in PopReviveService, and NPE in Broker2Client.

Findings

  • [Critical → Fixed] CommitLog.java:314 — Without the else break, a missing mapped file would cause an infinite loop since startOffset never advances. The fix correctly breaks out and logs a warning. Good catch.
  • [Critical → Fixed] PopReviveService.java:596 — Replacing inflightReviveRequestMap.remove(oldCK) inside a for-each loop with iterator.remove() is the correct fix for the ConcurrentModificationException. The iterator pattern is properly applied.
  • [Info] Broker2Client.java:256 — getConsumerGroupInfo(group) can return null when the consumer group doesn't exist. The null guard before .getChannelInfoTable() is correct. The existing null check on channelInfoTable at line 258 handles the null case downstream.

Suggestions

All three fixes address real production issues. The CommitLog infinite loop fix is particularly important as it could cause a broker thread to spin indefinitely. Consider adding a regression test for the getBulkData edge case if feasible.


Automated review by github-manager-bot

@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

Defensive fix with proper validation and test coverage. 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.

2 participants