rocketmq icon indicating copy to clipboard operation
rocketmq copied to clipboard

[Chore] improve `NettyRemotingAbstract` about timeout control

Open diaohancai opened this issue 1 year ago • 2 comments

Before Creating the Bug Report

  • [X] I found a bug, not just asking a question, which should be created in GitHub Discussions.

  • [X] I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.

  • [X] I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.

Runtime platform environment

Don't care.

RocketMQ version

branch: 4.9.x

JDK Version

Don't care.

Describe the Bug

org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#invokeSyncImpl

channel.writeAndFlush(request).addListener(new ChannelFutureListener() {
	@Override
	public void operationComplete(ChannelFuture f) throws Exception {
		if (f.isSuccess()) {
			responseFuture.setSendRequestOK(true);
			return;
		} else {
			responseFuture.setSendRequestOK(false);
		}

		responseTable.remove(opaque);
		responseFuture.setCause(f.cause());
		responseFuture.putResponse(null);
		log.warn("send a request command to channel <" + addr + "> failed.");
	}
});

RemotingCommand responseCommand = responseFuture.waitResponse(timeoutMillis);

org.apache.rocketmq.remoting.netty.ResponseFuture#putResponse

public void putResponse(final RemotingCommand responseCommand) {
	this.responseCommand = responseCommand;
	this.countDownLatch.countDown();
}
  1. responseFuture.waitResponse(timeoutMillis); -> this.countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); use countDownLatch to wait for asynchronous response.
  2. If f.isSuccess() == false, then call responseFuture.putResponse(null); to countDownLatch.countDown().
  3. But if f.isSuccess() == true, did not to countDownLatch.countDown(), cause responseFuture.waitResponse(timeoutMillis); always timeout after timeoutMillis.

Steps to Reproduce

Don't care.

What Did You Expect to See?

If f.isSuccess() == true, also countDownLatch.countDown(). And RemotingCommand responseCommand = responseFuture.waitResponse(timeoutMillis); is no need to wait for timeout.

What Did You See Instead?

Nothing.

Additional Context

No response

diaohancai avatar Jan 14 '24 14:01 diaohancai

I had the same problem as this,and client version is 4.7.0, broker version is 5.1.4 why f.isSuccess == false is necessary

javens0601 avatar Jan 16 '24 05:01 javens0601

I had the same problem as this,and client version is 4.7.0, broker version is 5.1.4 why f.isSuccess == false is necessary

what? RemotingCommand responseCommand = responseFuture.waitResponse(timeoutMillis) use countDownLatch to wait for asynchronous response. So when netty responded asynchronously, no matter f.isSuccess() or not, should call countDownLatch.countDown(). Otherwise responseFuture.waitResponse(timeoutMillis) always timeout after timeoutMillis.

diaohancai avatar Jan 17 '24 02:01 diaohancai