zjncs opened a new pull request, #11108:
URL: https://github.com/apache/rocketmq/pull/11108

   ## Motivation
   
   `TopicPublishInfo` exposes three `selectOneMessageQueue` overloads with 
inconsistent contracts:
   
   ```java
   // QueueFilter variant — guarded
   if (messageQueueList == null || messageQueueList.isEmpty()) {
       return null;
   }
   
   // no-arg variant — unguarded
   int index = this.sendWhichQueue.incrementAndGet();
   int pos = index % this.messageQueueList.size();   // NPE on null list, 
ArithmeticException (x % 0) on empty list
   ```
   
   A topic whose route exists but has no writable queue legitimately produces 
such an info object: `topicRouteData2TopicPublishInfo` adds nothing to the list 
when every `QueueData` is read-only or has `writeQueueNums == 0`, so `ok()` is 
false while the object itself is non-null.
   
   `MQFaultStrategy.selectOneMessageQueue` falls back to the unguarded no-arg 
variant, and the async-send retry path (`MQClientAPIImpl.onExceptionImpl`) is 
the one caller that only null-checks the info instead of checking `ok()` like 
every send entry point does.
   
   ## Modification
   
   - `TopicPublishInfo.selectOneMessageQueue()` and 
`selectOneMessageQueue(String lastBrokerName)`: return null when the queue list 
is null/empty, aligning with the QueueFilter variant.
   - `MQClientAPIImpl.onExceptionImpl`: apply the same `ok()` contract — a 
route-less info keeps the "retry the same broker" default instead of feeding 
the selector.
   
   No behavior change for existing callers: every other call site 
(sendDefaultImpl, EscapeBridge) already checks `ok()` before selecting.
   
   ## Test Evidence
   
   Fail-before (unpatched develop, new `TopicPublishInfoTest`):
   
   ```
   mvn -q -pl client test 
-Dtest='TopicPublishInfoTest#testSelectOneMessageQueueWithEmptyQueueList'
   Tests run: 1, Errors: 1 - java.lang.ArithmeticException: / by zero
   #testSelectOneMessageQueueWithNullQueueList      -> NullPointerException 
(List.size())
   #testSelectOneMessageQueueLastBrokerNameWithEmptyQueueList -> 
ArithmeticException: / by zero
   #testSelectOneMessageQueueLastBrokerNameWithNullQueueList   -> 
NullPointerException (List.size())
   ```
   
   Pass-after:
   
   ```
   mvn -q -pl client test 
-Dtest='TopicPublishInfoTest,SelectMessageQueueRetryTest'
   Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
   ```
   
   No associated issue (self-discovered during a client-module self-audit).


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