Search in sources :

Example 1 with RemoteServiceResponse

use of org.redisson.remote.RemoteServiceResponse 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 RemoteServiceResponse

use of org.redisson.remote.RemoteServiceResponse 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 3 with RemoteServiceResponse

use of org.redisson.remote.RemoteServiceResponse 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)3 RemoteServiceResponse (org.redisson.remote.RemoteServiceResponse)3 RemoteServiceAckTimeoutException (org.redisson.remote.RemoteServiceAckTimeoutException)2 RemoteServiceCancelResponse (org.redisson.remote.RemoteServiceCancelResponse)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 RemoteInvocationOptions (org.redisson.api.RemoteInvocationOptions)1 RemoteParams (org.redisson.remote.RemoteParams)1 RemoteServiceAck (org.redisson.remote.RemoteServiceAck)1 RemoteServiceRequest (org.redisson.remote.RemoteServiceRequest)1