unbridled-41 opened a new pull request, #11042:
URL: https://github.com/apache/rocketmq/pull/11042

   ### Problem / Evidence
   
   The split-metadata pagination loops terminate one entry too early. The 
client loops in `MQClientAPIImpl#getAllTopicConfig` / 
`#getAllSubscriptionGroup` break on `topicSeq >= totalTopicNum - 1` / `groupSeq 
>= totalGroupNum - 1`, while the broker pages `[seq, seq + maxNum)` with no 
overlap (`TopicConfigManager#subTopicConfig`, 
`SubscriptionGroupManager#subGroupTable`, `totalTopicNum = size()`).
   
   After page k the client holds `k·pageSize` entries, so the loop stops as 
soon as `k·pageSize >= N − 1` — which is already true when exactly one entry 
remains unfetched, i.e. for every **N ≡ 1 (mod pageSize)**. Example: 2001 
topics with the default page size 2000 → page 1 returns 2000 entries, `2000 >= 
2001 − 1` holds, the loop breaks, topic #2001 is never requested. No error, no 
retry — silently truncated metadata.
   
   The identical off-by-one exists in `BrokerOuterAPI#getAllTopicConfig` (used 
by `SlaveSynchronize#syncTopicConfig`) and 
`BrokerOuterAPI#getAllSubscriptionGroup`: a slave whose master has N ≡ 1 (mod 
2000) topics permanently misses the last topic — and the dataVersion comparison 
then matches, so no later resync repairs it.
   
   Regression tests 
`MQClientAPIImplTest#testGetAllTopicConfigFetchesLastEntryWhenTotalIsOneOverPageSize`
 and `#testGetAllSubscriptionGroupFetchesLastEntryWhenTotalIsOneOverPageSize` 
fail before the fix (`expected:<101> but was:<100>`) and pass after.
   
   ### Root cause / Fix
   
   Terminate when `seq >= totalNum`. When the page completes the set the 
condition still breaks immediately; when exactly one entry remains it now 
continues and fetches the final page (a subsequent empty page still terminates 
because `seq >= totalNum` remains true). Applied to all four occurrences of the 
same defect: `MQClientAPIImpl` (topic + subscription group) and 
`BrokerOuterAPI` (topic + subscription group).
   
   ### Priority
   
   PRIORITY = 74:影响 28(静默元数据截断——mqadmin 导出/同步工具丢最后一个 topic/消费组,SlaveSynchronize 
全量同步永久缺最新 topic 且不会自愈)+ 波及范围 14(4 处同类循环、client+broker 两端)+ 可复现性 20(确定性单元测试,N = 
pageSize + 1 边界)+ 维护价值 12(一行终止条件 ×4)。FIX_CONFIDENCE = 90。
   
   ### Tests
   
   - `mvn -pl client test 
-Dtest=MQClientAPIImplTest#testGetAllTopicConfigFetchesLastEntryWhenTotalIsOneOverPageSize`
     - before fix (ff8f6f74c + test only): `Tests run: 1, Failures: 1` — 
`expected:<101> but was:<100>`
     - after fix: `Tests run: 1, Failures: 0`
   - same for 
`testGetAllSubscriptionGroupFetchesLastEntryWhenTotalIsOneOverPageSize`
   - `mvn -pl client test -Dtest=MQClientAPIImplTest`: `Tests run: 135, 
Failures: 0, Errors: 0`
   - `mvn -pl broker compile`: OK (BrokerOuterAPI change)
   
   ### Risk
   
   Low. The only behavior change is that exactly one extra page request is 
issued in the boundary case (and none in any other case — for all other N the 
old and new conditions break at the same page). Old-version brokers that do not 
return `totalTopicNum`/`totalGroupNum` are unaffected (the null-compatibility 
break precedes this condition).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to