Search in sources :

Example 1 with SemaphoreReleaseOnlyOnce

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);
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) InvokeCallback(org.apache.rocketmq.remoting.InvokeCallback) Semaphore(java.util.concurrent.Semaphore) SemaphoreReleaseOnlyOnce(org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce) Test(org.junit.Test)

Example 2 with SemaphoreReleaseOnlyOnce

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);
        }
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) RemotingSendRequestException(org.apache.rocketmq.remoting.exception.RemotingSendRequestException) RemotingTimeoutException(org.apache.rocketmq.remoting.exception.RemotingTimeoutException) ChannelFutureListener(io.netty.channel.ChannelFutureListener) RemotingTooMuchRequestException(org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RemotingSendRequestException(org.apache.rocketmq.remoting.exception.RemotingSendRequestException) RemotingTimeoutException(org.apache.rocketmq.remoting.exception.RemotingTimeoutException) SemaphoreReleaseOnlyOnce(org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce) RemotingTooMuchRequestException(org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException)

Example 3 with SemaphoreReleaseOnlyOnce

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);
        }
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelFutureListener(io.netty.channel.ChannelFutureListener) RemotingTooMuchRequestException(org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RemotingSendRequestException(org.apache.rocketmq.remoting.exception.RemotingSendRequestException) RemotingTimeoutException(org.apache.rocketmq.remoting.exception.RemotingTimeoutException) SemaphoreReleaseOnlyOnce(org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce) RemotingTooMuchRequestException(org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException) RemotingSendRequestException(org.apache.rocketmq.remoting.exception.RemotingSendRequestException) RemotingTimeoutException(org.apache.rocketmq.remoting.exception.RemotingTimeoutException)

Example 4 with SemaphoreReleaseOnlyOnce

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);
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) InvokeCallback(org.apache.rocketmq.remoting.InvokeCallback) Semaphore(java.util.concurrent.Semaphore) SemaphoreReleaseOnlyOnce(org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce) Test(org.junit.Test)

Example 5 with SemaphoreReleaseOnlyOnce

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);
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) Semaphore(java.util.concurrent.Semaphore) SemaphoreReleaseOnlyOnce(org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce) Test(org.junit.Test)

Aggregations

SemaphoreReleaseOnlyOnce (org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce)7 ChannelFuture (io.netty.channel.ChannelFuture)4 ChannelFutureListener (io.netty.channel.ChannelFutureListener)4 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)4 RemotingSendRequestException (org.apache.rocketmq.remoting.exception.RemotingSendRequestException)4 RemotingTimeoutException (org.apache.rocketmq.remoting.exception.RemotingTimeoutException)4 RemotingTooMuchRequestException (org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException)4 Semaphore (java.util.concurrent.Semaphore)3 RemotingCommand (org.apache.rocketmq.remoting.protocol.RemotingCommand)3 Test (org.junit.Test)3 InvokeCallback (org.apache.rocketmq.remoting.InvokeCallback)2