Skip to content

[ISSUE #C2] Count down the queryMessage latch when the invocation fails - #11105

Open
zjncs wants to merge 1 commit into
apache:developfrom
zjncs:fix/mq-admin-impl-query-message-latch
Open

[ISSUE #C2] Count down the queryMessage latch when the invocation fails#11105
zjncs wants to merge 1 commit into
apache:developfrom
zjncs:fix/mq-admin-impl-query-message-latch

Conversation

@zjncs

@zjncs zjncs commented Sep 9, 2026

Copy link
Copy Markdown

Motivation

MQAdminImpl.queryMessage fans out one asynchronous query per broker and waits on a CountDownLatch(brokerAddrs.size()). The latch is released by the InvokeCallback (operationSucceed/operationFail), but if MQClientAPIImpl.queryMessage itself throws synchronously — e.g. RemotingConnectException/RemotingTimeoutException for an unreachable broker — no callback is ever invoked, and the catch block only logs:

} catch (Exception e) {
    log.warn("queryMessage exception", e);
}
...
boolean ok = countDownLatch.await(timeoutMillis * 4, TimeUnit.MILLISECONDS);

The caller then blocks for the full timeoutMillis * 4 window — 24 seconds with the default timeoutMillis of 6s — before getting the "no message" answer, even though the outcome was already known. Any tool/admin call that queries by key while one broker is down pays this stall.

Modifications

  • Add countDownLatch.countDown(); in the catch block, releasing this broker's count exactly as the callback would have.

Verification

Fail-before (new test on unpatched code — the per-broker invoke is mocked to throw, timeoutMillis=200):

MQAdminImplTest.assertQueryMessageNotBlockedWhenInvokeThrows:192
  queryMessage should not wait for the whole latch timeout, elapsed=846

Pass-after — full MQAdminImplTest (11 existing + 1 new); the same call now returns in single-digit milliseconds:

mvn -pl client test -Dtest='MQAdminImplTest'
Tests run: 12, Failures: 0, Errors: 0, Skipped: 0

MQAdminImpl.queryMessage registers an InvokeCallback that releases the
per-broker CountDownLatch, but when MQClientAPIImpl.queryMessage itself
throws synchronously (e.g. RemotingConnectException for an unreachable
broker) the callback never fires and the catch block only logs. The
await(timeoutMillis * 4) below then blocks for the whole window — 24s
with the default timeoutMillis of 6s — before reporting that no message
was found. Release this broker's latch count in the catch block.

Signed-off-by: zjncs <18910855655@163.com>
Copilot AI lite review requested due to automatic review settings September 9, 2026 10:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@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

Correct fix for a real stall — when MQClientAPIImpl.queryMessage throws synchronously (e.g. RemotingConnectException), the callback never fires and the latch is never decremented, causing the caller to block for the full timeoutMillis * 4 (24s default). Adding countDownLatch.countDown() in the catch block is the minimal correct fix. Test validates the timing improvement.


Automated review by github-manager

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.

3 participants