use of org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce in project rocketmq by apache.
the class NettyRemotingAbstractTest method testProcessResponseCommand_RunCallBackInCurrentThread.
@Test
public void testProcessResponseCommand_RunCallBackInCurrentThread() throws InterruptedException {
final Semaphore semaphore = new Semaphore(0);
ResponseFuture responseFuture = new ResponseFuture(1, 3000, new InvokeCallback() {
@Override
public void operationComplete(final ResponseFuture responseFuture) {
assertThat(semaphore.availablePermits()).isEqualTo(0);
}
}, new SemaphoreReleaseOnlyOnce(semaphore));
remotingAbstract.responseTable.putIfAbsent(1, responseFuture);
when(remotingAbstract.getCallbackExecutor()).thenReturn(null);
RemotingCommand response = RemotingCommand.createResponseCommand(0, "Foo");
response.setOpaque(1);
remotingAbstract.processResponseCommand(null, response);
// Acquire the release permit after call back finished in current thread
semaphore.acquire(1);
assertThat(semaphore.availablePermits()).isEqualTo(0);
}
use of org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce in project rocketmq by apache.
the class NettyRemotingAbstract method invokeOnewayImpl.
public void invokeOnewayImpl(final Channel channel, final RemotingCommand request, final long timeoutMillis) throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
request.markOnewayRPC();
boolean acquired = this.semaphoreOneway.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS);
if (acquired) {
final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreOneway);
try {
channel.writeAndFlush(request).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture f) throws Exception {
once.release();
if (!f.isSuccess()) {
log.warn("send a request command to channel <" + channel.remoteAddress() + "> failed.");
}
}
});
} catch (Exception e) {
once.release();
log.warn("write send a request command to channel <" + channel.remoteAddress() + "> failed.");
throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e);
}
} else {
if (timeoutMillis <= 0) {
throw new RemotingTooMuchRequestException("invokeOnewayImpl invoke too fast");
} else {
String info = String.format("invokeOnewayImpl tryAcquire semaphore timeout, %dms, waiting thread nums: %d semaphoreAsyncValue: %d", timeoutMillis, this.semaphoreOneway.getQueueLength(), this.semaphoreOneway.availablePermits());
log.warn(info);
throw new RemotingTimeoutException(info);
}
}
}
use of org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce in project rocketmq by apache.
the class NettyRemotingAbstract method invokeAsyncImpl.
public void invokeAsyncImpl(final Channel channel, final RemotingCommand request, final long timeoutMillis, final InvokeCallback invokeCallback) throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
final int opaque = request.getOpaque();
boolean acquired = this.semaphoreAsync.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS);
if (acquired) {
final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreAsync);
final ResponseFuture responseFuture = new ResponseFuture(opaque, timeoutMillis, invokeCallback, once);
this.responseTable.put(opaque, responseFuture);
try {
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);
}
responseFuture.putResponse(null);
responseTable.remove(opaque);
try {
executeInvokeCallback(responseFuture);
} catch (Throwable e) {
log.warn("excute callback in writeAndFlush addListener, and callback throw", e);
} finally {
responseFuture.release();
}
log.warn("send a request command to channel <{}> failed.", RemotingHelper.parseChannelRemoteAddr(channel));
}
});
} catch (Exception e) {
responseFuture.release();
log.warn("send a request command to channel <" + RemotingHelper.parseChannelRemoteAddr(channel) + "> Exception", e);
throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e);
}
} else {
if (timeoutMillis <= 0) {
throw new RemotingTooMuchRequestException("invokeAsyncImpl invoke too fast");
} else {
String info = String.format("invokeAsyncImpl tryAcquire semaphore timeout, %dms, waiting thread nums: %d semaphoreAsyncValue: %d", timeoutMillis, this.semaphoreAsync.getQueueLength(), this.semaphoreAsync.availablePermits());
log.warn(info);
throw new RemotingTimeoutException(info);
}
}
}
use of org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce in project rocketmq by apache.
the class NettyRemotingAbstractTest method testProcessResponseCommand.
@Test
public void testProcessResponseCommand() throws InterruptedException {
final Semaphore semaphore = new Semaphore(0);
ResponseFuture responseFuture = new ResponseFuture(1, 3000, new InvokeCallback() {
@Override
public void operationComplete(final ResponseFuture responseFuture) {
assertThat(semaphore.availablePermits()).isEqualTo(0);
}
}, new SemaphoreReleaseOnlyOnce(semaphore));
remotingAbstract.responseTable.putIfAbsent(1, responseFuture);
RemotingCommand response = RemotingCommand.createResponseCommand(0, "Foo");
response.setOpaque(1);
remotingAbstract.processResponseCommand(null, response);
// Acquire the release permit after call back
semaphore.acquire(1);
assertThat(semaphore.availablePermits()).isEqualTo(0);
}
use of org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce in project rocketmq by apache.
the class NettyRemotingAbstractTest method testProcessResponseCommand_NullCallBack.
@Test
public void testProcessResponseCommand_NullCallBack() throws InterruptedException {
final Semaphore semaphore = new Semaphore(0);
ResponseFuture responseFuture = new ResponseFuture(1, 3000, null, new SemaphoreReleaseOnlyOnce(semaphore));
remotingAbstract.responseTable.putIfAbsent(1, responseFuture);
RemotingCommand response = RemotingCommand.createResponseCommand(0, "Foo");
response.setOpaque(1);
remotingAbstract.processResponseCommand(null, response);
assertThat(semaphore.availablePermits()).isEqualTo(1);
}
Aggregations