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