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());
}
});
}
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);
}
}
}
});
}
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);
}
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);
}
}
Aggregations