Search in sources :

Example 6 with RemoteInvocationOptions

use of org.redisson.api.RemoteInvocationOptions in project redisson by redisson.

the class BaseRemoteService method sync.

private <T> T sync(final Class<T> remoteInterface, final RemoteInvocationOptions options) {
    // local copy of the options, to prevent mutation
    final RemoteInvocationOptions optionsCopy = new RemoteInvocationOptions(options);
    final String toString = getClass().getSimpleName() + "-" + remoteInterface.getSimpleName() + "-proxy-" + generateRequestId();
    InvocationHandler handler = new InvocationHandler() {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (method.getName().equals("toString")) {
                return toString;
            } else if (method.getName().equals("equals")) {
                return proxy == args[0];
            } else if (method.getName().equals("hashCode")) {
                return toString.hashCode();
            }
            if (!optionsCopy.isResultExpected() && !(method.getReturnType().equals(Void.class) || method.getReturnType().equals(Void.TYPE)))
                throw new IllegalArgumentException("The noResult option only supports void return value");
            String requestId = generateRequestId();
            String requestQueueName = getRequestQueueName(remoteInterface);
            RBlockingQueue<RemoteServiceRequest> requestQueue = redisson.getBlockingQueue(requestQueueName, getCodec());
            RemoteServiceRequest request = new RemoteServiceRequest(requestId, method.getName(), getMethodSignatures(method), args, optionsCopy, System.currentTimeMillis());
            requestQueue.add(request);
            RBlockingQueue<RRemoteServiceResponse> responseQueue = null;
            if (optionsCopy.isAckExpected() || optionsCopy.isResultExpected()) {
                String responseName = getResponseQueueName(remoteInterface, requestId);
                responseQueue = redisson.getBlockingQueue(responseName, getCodec());
            }
            // poll for the ack only if expected
            if (optionsCopy.isAckExpected()) {
                String ackName = getAckName(remoteInterface, requestId);
                RemoteServiceAck ack = (RemoteServiceAck) responseQueue.poll(optionsCopy.getAckTimeoutInMillis(), TimeUnit.MILLISECONDS);
                if (ack == null) {
                    ack = tryPollAckAgain(optionsCopy, responseQueue, ackName);
                    if (ack == null) {
                        throw new RemoteServiceAckTimeoutException("No ACK response after " + optionsCopy.getAckTimeoutInMillis() + "ms for request: " + request);
                    }
                }
                redisson.getBucket(ackName).delete();
            }
            // poll for the response only if expected
            if (optionsCopy.isResultExpected()) {
                RemoteServiceResponse response = (RemoteServiceResponse) responseQueue.poll(optionsCopy.getExecutionTimeoutInMillis(), TimeUnit.MILLISECONDS);
                if (response == null) {
                    throw new RemoteServiceTimeoutException("No response1 after " + optionsCopy.getExecutionTimeoutInMillis() + "ms for request: " + request);
                }
                if (response.getError() != null) {
                    throw response.getError();
                }
                return response.getResult();
            }
            return null;
        }
    };
    return (T) Proxy.newProxyInstance(remoteInterface.getClassLoader(), new Class[] { remoteInterface }, handler);
}
Also used : RemoteServiceTimeoutException(org.redisson.remote.RemoteServiceTimeoutException) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler) RemoteInvocationOptions(org.redisson.api.RemoteInvocationOptions) RemoteServiceRequest(org.redisson.remote.RemoteServiceRequest) RRemoteServiceResponse(org.redisson.remote.RRemoteServiceResponse) RemoteServiceAckTimeoutException(org.redisson.remote.RemoteServiceAckTimeoutException) RemoteServiceResponse(org.redisson.remote.RemoteServiceResponse) RRemoteServiceResponse(org.redisson.remote.RRemoteServiceResponse) RemoteServiceAck(org.redisson.remote.RemoteServiceAck)

Example 7 with RemoteInvocationOptions

use of org.redisson.api.RemoteInvocationOptions in project redisson by redisson.

the class RedissonRemoteServiceTest method testNoAckWithoutResultInvocations.

@Test
public void testNoAckWithoutResultInvocations() throws InterruptedException {
    RedissonClient server = createInstance();
    RedissonClient client = createInstance();
    try {
        server.getRemoteService().register(RemoteInterface.class, new RemoteImpl());
        // no ack fire and forget
        RemoteInvocationOptions options = RemoteInvocationOptions.defaults().noAck().noResult();
        RemoteInterface service = client.getRemoteService().get(RemoteInterface.class, options);
        RemoteInterface invalidService = client.getRemoteService("Invalid").get(RemoteInterface.class, options);
        service.voidMethod("noAck/noResult", 100L);
        try {
            service.resultMethod(100L);
            Assert.fail();
        } catch (Exception e) {
            assertThat(e).isInstanceOf(IllegalArgumentException.class);
        }
        try {
            service.errorMethod();
        } catch (IOException e) {
            Assert.fail("noAck with noResult options should not throw server side exception");
        }
        try {
            service.errorMethodWithCause();
        } catch (Exception e) {
            Assert.fail("noAck with noResult options should not throw server side exception");
        }
        long time = System.currentTimeMillis();
        service.timeoutMethod();
        time = System.currentTimeMillis() - time;
        assertThat(time).describedAs("noAck with noResult options should not wait for the server to return a response").isLessThan(2000);
        try {
            invalidService.voidMethod("noAck/noResult", 21L);
        } catch (Exception e) {
            Assert.fail("noAck with noResult options should not throw any exception even while invoking a service in an unregistered services namespace");
        }
    } finally {
        client.shutdown();
        server.shutdown();
    }
}
Also used : RedissonClient(org.redisson.api.RedissonClient) IOException(java.io.IOException) RemoteServiceTimeoutException(org.redisson.remote.RemoteServiceTimeoutException) IOException(java.io.IOException) NotSerializableException(java.io.NotSerializableException) ExecutionException(java.util.concurrent.ExecutionException) RemoteServiceAckTimeoutException(org.redisson.remote.RemoteServiceAckTimeoutException) RemoteInvocationOptions(org.redisson.api.RemoteInvocationOptions) Test(org.junit.Test)

Aggregations

RemoteInvocationOptions (org.redisson.api.RemoteInvocationOptions)7 RemoteServiceAckTimeoutException (org.redisson.remote.RemoteServiceAckTimeoutException)6 RemoteServiceTimeoutException (org.redisson.remote.RemoteServiceTimeoutException)6 IOException (java.io.IOException)5 NotSerializableException (java.io.NotSerializableException)4 ExecutionException (java.util.concurrent.ExecutionException)4 Test (org.junit.Test)4 RedissonClient (org.redisson.api.RedissonClient)4 InvocationHandler (java.lang.reflect.InvocationHandler)2 Method (java.lang.reflect.Method)2 RemoteServiceAck (org.redisson.remote.RemoteServiceAck)2 RemoteServiceRequest (org.redisson.remote.RemoteServiceRequest)2 Future (io.netty.util.concurrent.Future)1 FutureListener (io.netty.util.concurrent.FutureListener)1 RBlockingQueue (org.redisson.api.RBlockingQueue)1 RFuture (org.redisson.api.RFuture)1 RemotePromise (org.redisson.executor.RemotePromise)1 RRemoteServiceResponse (org.redisson.remote.RRemoteServiceResponse)1 RemoteServiceCancelRequest (org.redisson.remote.RemoteServiceCancelRequest)1 RemoteServiceResponse (org.redisson.remote.RemoteServiceResponse)1