use of org.apache.ignite.raft.jraft.error.InvokeTimeoutException in project ignite-3 by apache.
the class AbstractClientServiceTest method testInvokeWithDoneOnException.
@Test
public void testInvokeWithDoneOnException() throws Exception {
InvokeContext invokeCtx = new InvokeContext();
ArgumentCaptor<InvokeCallback> callbackArg = ArgumentCaptor.forClass(InvokeCallback.class);
PingRequest request = TestUtils.createPingRequest();
MockRpcResponseClosure<ErrorResponse> done = new MockRpcResponseClosure<>();
Future<Message> future = this.clientService.invokeWithDone(this.endpoint, request, invokeCtx, done, -1);
Mockito.verify(this.rpcClient).invokeAsync(eq(this.endpoint), eq(request), eq(invokeCtx), callbackArg.capture(), eq((long) this.rpcOptions.getRpcDefaultTimeout()));
InvokeCallback cb = callbackArg.getValue();
assertNotNull(cb);
assertNotNull(future);
assertNull(done.getResponse());
assertNull(done.status);
assertFalse(future.isDone());
cb.complete(null, new InvokeTimeoutException());
done.latch.await();
assertNotNull(done.status);
assertEquals(RaftError.ETIMEDOUT.getNumber(), done.status.getCode());
}
use of org.apache.ignite.raft.jraft.error.InvokeTimeoutException in project ignite-3 by apache.
the class AbstractClientService method invokeWithDone.
public <T extends Message> CompletableFuture<Message> invokeWithDone(final Endpoint endpoint, final Message request, final InvokeContext ctx, final RpcResponseClosure<T> done, final int timeoutMs, final Executor rpcExecutor) {
final RpcClient rc = this.rpcClient;
final FutureImpl<Message> future = new FutureImpl<>();
final Executor currExecutor = rpcExecutor != null ? rpcExecutor : this.rpcExecutor;
try {
if (rc == null) {
// TODO asch replace with ignite exception, check all places IGNITE-14832
future.completeExceptionally(new IllegalStateException("Client service is uninitialized."));
// should be in another thread to avoid dead locking.
Utils.runClosureInExecutor(currExecutor, done, new Status(RaftError.EINTERNAL, "Client service is uninitialized."));
return future;
}
return rc.invokeAsync(endpoint, request, ctx, new InvokeCallback() {
@Override
public void complete(final Object result, final Throwable err) {
if (err == null) {
Status status = Status.OK();
Message msg;
if (result instanceof ErrorResponse) {
status = handleErrorResponse((ErrorResponse) result);
msg = (Message) result;
} else {
msg = (Message) result;
}
if (done != null) {
try {
if (status.isOk()) {
done.setResponse((T) msg);
}
done.run(status);
} catch (final Throwable t) {
LOG.error("Fail to run RpcResponseClosure, the request is {}.", t, request);
}
}
if (!future.isDone()) {
future.complete(msg);
}
} else {
if (ThrowUtil.hasCause(err, null, ConnectException.class))
// Force logical reconnect.
readyAddresses.remove(endpoint.toString());
if (done != null) {
try {
done.run(new Status(err instanceof InvokeTimeoutException ? RaftError.ETIMEDOUT : RaftError.EINTERNAL, "RPC exception:" + err.getMessage()));
} catch (final Throwable t) {
LOG.error("Fail to run RpcResponseClosure, the request is {}.", t, request);
}
}
if (!future.isDone()) {
future.completeExceptionally(err);
}
}
}
@Override
public Executor executor() {
return currExecutor;
}
}, timeoutMs <= 0 ? this.rpcOptions.getRpcDefaultTimeout() : timeoutMs);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
future.completeExceptionally(e);
// should be in another thread to avoid dead locking.
Utils.runClosureInExecutor(currExecutor, done, new Status(RaftError.EINTR, "Sending rpc was interrupted"));
} catch (final RemotingException e) {
future.completeExceptionally(e);
// should be in another thread to avoid dead locking.
Utils.runClosureInExecutor(currExecutor, done, new Status(RaftError.EINTERNAL, "Fail to send a RPC request:" + e.getMessage()));
}
return future;
}
use of org.apache.ignite.raft.jraft.error.InvokeTimeoutException in project ignite-3 by apache.
the class IgniteRpcClient method invokeAsync.
/**
* {@inheritDoc}
*/
@Override
public CompletableFuture<Message> invokeAsync(Endpoint endpoint, Object request, InvokeContext ctx, InvokeCallback callback, long timeoutMs) {
CompletableFuture<Message> fut = new CompletableFuture<>();
fut.orTimeout(timeoutMs, TimeUnit.MILLISECONDS).whenComplete((res, err) -> {
assert !(res == null && err == null) : res + " " + err;
if (err == null && recordPred != null && recordPred.test(res, this.toString()))
recordedMsgs.add(new Object[] { res, this.toString(), fut.hashCode(), System.currentTimeMillis(), null });
if (err instanceof ExecutionException)
err = new RemotingException(err);
else if (// Translate timeout exception.
err instanceof TimeoutException)
err = new InvokeTimeoutException();
Throwable finalErr = err;
// Avoid deadlocks if a closure has completed in the same thread.
Utils.runInThread(callback.executor(), () -> callback.complete(res, finalErr));
});
// Future hashcode used as corellation id.
if (recordPred != null && recordPred.test(request, endpoint.toString()))
recordedMsgs.add(new Object[] { request, endpoint.toString(), fut.hashCode(), System.currentTimeMillis(), null });
synchronized (this) {
if (blockPred != null && blockPred.test(request, endpoint.toString())) {
Object[] msgData = { request, endpoint.toString(), fut.hashCode(), System.currentTimeMillis(), (Runnable) () -> send(endpoint, request, fut, timeoutMs) };
blockedMsgs.add(msgData);
LOG.info("Blocked message to={} id={} msg={}", endpoint.toString(), msgData[2], S.toString(request));
return fut;
}
}
send(endpoint, request, fut, timeoutMs);
return fut;
}
Aggregations