Files
rocketmq/client
Jiahua Wang 3373f284e6 [ISSUE #10613] Fix async request-reply RequestCallback firing multiple times (#10614)
- DefaultMQProducerImpl#request(Message, RequestCallback, long): drop the
  executeRequestCallback() call in the async send onSuccess so a send success
  no longer delivers a premature onSuccess(null); align with the other async
  request overloads which only set sendRequestOk here.
- RequestResponseFuture: add an AtomicBoolean executeCallbackOnlyOnce guard so
  the callback fires at most once even if the reply and timeout paths race.
- RequestFutureHolder#scanExpiredRequest: use ConcurrentHashMap.remove(key) to
  atomically claim ownership instead of iterator.remove(); also fix the log
  placeholder concatenation.
- ClientRemotingProcessor#processReplyMessage: use atomic remove(correlationId)
  and route the reply through executeRequestCallback so the single-shot guard
  covers the reply-success path too.
- Add RequestResponseFutureTest cases for success-then-timeout and concurrent
  single-callback semantics.

Co-authored-by: wangjiahua.wjh <wangjiahua.wjh@alibaba-inc.com>
2026-07-17 18:43:41 +08:00
..