Search in sources :

Example 1 with RRemoteServiceResponse

use of org.redisson.remote.RRemoteServiceResponse in project redisson by redisson.

the class BaseRemoteService method awaitResultAsync.

protected void awaitResultAsync(final RemoteInvocationOptions optionsCopy, final RemotePromise<Object> result, final RemoteServiceRequest request, final String responseName) {
    // poll for the response only if expected
    if (!optionsCopy.isResultExpected()) {
        return;
    }
    RBlockingQueue<RRemoteServiceResponse> responseQueue = redisson.getBlockingQueue(responseName, getCodec());
    RFuture<RRemoteServiceResponse> responseFuture = responseQueue.pollAsync(optionsCopy.getExecutionTimeoutInMillis(), TimeUnit.MILLISECONDS);
    responseFuture.addListener(new FutureListener<RRemoteServiceResponse>() {

        @Override
        public void operationComplete(Future<RRemoteServiceResponse> future) throws Exception {
            if (!future.isSuccess()) {
                result.tryFailure(future.cause());
                return;
            }
            if (future.getNow() == null) {
                RemoteServiceTimeoutException e = new RemoteServiceTimeoutException("No response after " + optionsCopy.getExecutionTimeoutInMillis() + "ms for request: " + request);
                result.tryFailure(e);
                return;
            }
            if (future.getNow() instanceof RemoteServiceCancelResponse) {
                result.doCancel();
                return;
            }
            RemoteServiceResponse response = (RemoteServiceResponse) future.getNow();
            if (response.getError() != null) {
                result.tryFailure(response.getError());
                return;
            }
            result.trySuccess(response.getResult());
        }
    });
}
Also used : RemoteServiceTimeoutException(org.redisson.remote.RemoteServiceTimeoutException) RRemoteServiceResponse(org.redisson.remote.RRemoteServiceResponse) RemoteServiceTimeoutException(org.redisson.remote.RemoteServiceTimeoutException) IOException(java.io.IOException) RemoteServiceAckTimeoutException(org.redisson.remote.RemoteServiceAckTimeoutException) RemoteServiceResponse(org.redisson.remote.RemoteServiceResponse) RRemoteServiceResponse(org.redisson.remote.RRemoteServiceResponse) RemoteServiceCancelResponse(org.redisson.remote.RemoteServiceCancelResponse)

Example 2 with RRemoteServiceResponse

use of org.redisson.remote.RRemoteServiceResponse in project redisson by redisson.

the class RedissonRemoteService method executeMethod.

private <T> void executeMethod(final Class<T> remoteInterface, final RBlockingQueue<RemoteServiceRequest> requestQueue, final ExecutorService executor, final RemoteServiceRequest request) {
    final RemoteServiceMethod method = beans.get(new RemoteServiceKey(remoteInterface, request.getMethodName(), request.getSignatures()));
    final String responseName = getResponseQueueName(remoteInterface, request.getRequestId());
    RBlockingQueue<RemoteServiceCancelRequest> cancelRequestQueue = redisson.getBlockingQueue(getCancelRequestQueueName(remoteInterface, request.getRequestId()), getCodec());
    final RFuture<RemoteServiceCancelRequest> cancelRequestFuture = cancelRequestQueue.takeAsync();
    final AtomicReference<RRemoteServiceResponse> responseHolder = new AtomicReference<RRemoteServiceResponse>();
    final java.util.concurrent.Future<?> submitFuture = executor.submit(new Runnable() {

        @Override
        public void run() {
            invokeMethod(remoteInterface, requestQueue, request, method, responseName, executor, cancelRequestFuture, responseHolder);
        }
    });
    cancelRequestFuture.addListener(new FutureListener<RemoteServiceCancelRequest>() {

        @Override
        public void operationComplete(Future<RemoteServiceCancelRequest> future) throws Exception {
            if (!future.isSuccess()) {
                return;
            }
            boolean res = submitFuture.cancel(future.getNow().isMayInterruptIfRunning());
            if (res) {
                RemoteServiceCancelResponse response = new RemoteServiceCancelResponse();
                if (!responseHolder.compareAndSet(null, response)) {
                    response = new RemoteServiceCancelResponse(false);
                }
                // could be removed not from future object
                if (future.getNow().getResponseId() != null) {
                    String cancelResponseName = getResponseQueueName(remoteInterface, future.getNow().getResponseId());
                    send(60 * 1000, cancelResponseName, response);
                }
            }
        }
    });
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) RemoteServiceCancelResponse(org.redisson.remote.RemoteServiceCancelResponse) RemoteServiceCancelRequest(org.redisson.remote.RemoteServiceCancelRequest) RemoteServiceKey(org.redisson.remote.RemoteServiceKey) RemoteServiceMethod(org.redisson.remote.RemoteServiceMethod) RRemoteServiceResponse(org.redisson.remote.RRemoteServiceResponse)

Example 3 with RRemoteServiceResponse

use of org.redisson.remote.RRemoteServiceResponse 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 4 with RRemoteServiceResponse

use of org.redisson.remote.RRemoteServiceResponse in project redisson by redisson.

the class RedissonRemoteService method invokeMethod.

private <T> void invokeMethod(final Class<T> remoteInterface, final RBlockingQueue<RemoteServiceRequest> requestQueue, final RemoteServiceRequest request, RemoteServiceMethod method, String responseName, final ExecutorService executor, RFuture<RemoteServiceCancelRequest> cancelRequestFuture, final AtomicReference<RRemoteServiceResponse> responseHolder) {
    try {
        if (method.getBean() instanceof RemoteParams) {
            ((RemoteParams) method.getBean()).setRequestId(request.getRequestId());
        }
        Object result = method.getMethod().invoke(method.getBean(), request.getArgs());
        RemoteServiceResponse response = new RemoteServiceResponse(result);
        responseHolder.compareAndSet(null, response);
    } catch (Exception e) {
        RemoteServiceResponse response = new RemoteServiceResponse(e.getCause());
        responseHolder.compareAndSet(null, response);
        log.error("Can't execute: " + request, e);
    }
    if (cancelRequestFuture != null) {
        cancelRequestFuture.cancel(false);
    }
    // send the response only if expected or task was canceled
    if (request.getOptions().isResultExpected() || responseHolder.get() instanceof RemoteServiceCancelResponse) {
        long timeout = 60 * 1000;
        if (request.getOptions().getExecutionTimeoutInMillis() != null) {
            timeout = request.getOptions().getExecutionTimeoutInMillis();
        }
        RFuture<List<?>> clientsFuture = send(timeout, responseName, responseHolder.get());
        clientsFuture.addListener(new FutureListener<List<?>>() {

            @Override
            public void operationComplete(Future<List<?>> future) throws Exception {
                if (!future.isSuccess()) {
                    log.error("Can't send response: " + responseHolder.get() + " for request: " + request, future.cause());
                    if (future.cause() instanceof RedissonShutdownException) {
                        return;
                    }
                }
                // re-subscribe anyways (fail or success) after the send
                // (response)
                subscribe(remoteInterface, requestQueue, executor);
            }
        });
    } else {
        // re-subscribe anyways after the method invocation
        subscribe(remoteInterface, requestQueue, executor);
    }
}
Also used : List(java.util.List) RemoteParams(org.redisson.remote.RemoteParams) RemoteServiceResponse(org.redisson.remote.RemoteServiceResponse) RRemoteServiceResponse(org.redisson.remote.RRemoteServiceResponse) RemoteServiceCancelResponse(org.redisson.remote.RemoteServiceCancelResponse)

Aggregations

RRemoteServiceResponse (org.redisson.remote.RRemoteServiceResponse)4 RemoteServiceCancelResponse (org.redisson.remote.RemoteServiceCancelResponse)3 RemoteServiceResponse (org.redisson.remote.RemoteServiceResponse)3 RemoteServiceAckTimeoutException (org.redisson.remote.RemoteServiceAckTimeoutException)2 RemoteServiceTimeoutException (org.redisson.remote.RemoteServiceTimeoutException)2 IOException (java.io.IOException)1 InvocationHandler (java.lang.reflect.InvocationHandler)1 Method (java.lang.reflect.Method)1 List (java.util.List)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 RemoteInvocationOptions (org.redisson.api.RemoteInvocationOptions)1 RemoteParams (org.redisson.remote.RemoteParams)1 RemoteServiceAck (org.redisson.remote.RemoteServiceAck)1 RemoteServiceCancelRequest (org.redisson.remote.RemoteServiceCancelRequest)1 RemoteServiceKey (org.redisson.remote.RemoteServiceKey)1 RemoteServiceMethod (org.redisson.remote.RemoteServiceMethod)1 RemoteServiceRequest (org.redisson.remote.RemoteServiceRequest)1