use of org.apache.ratis.protocol.exceptions.NotLeaderException in project incubator-ratis by apache.
the class ClientProtoUtils method toRaftClientReply.
static RaftClientReply toRaftClientReply(RaftClientReplyProto replyProto) {
final RaftRpcReplyProto rp = replyProto.getRpcReply();
final RaftGroupMemberId serverMemberId = ProtoUtils.toRaftGroupMemberId(rp.getReplyId(), rp.getRaftGroupId());
final RaftException e;
if (replyProto.getExceptionDetailsCase().equals(NOTLEADEREXCEPTION)) {
NotLeaderExceptionProto nleProto = replyProto.getNotLeaderException();
final RaftPeer suggestedLeader = nleProto.hasSuggestedLeader() ? ProtoUtils.toRaftPeer(nleProto.getSuggestedLeader()) : null;
final List<RaftPeer> peers = ProtoUtils.toRaftPeers(nleProto.getPeersInConfList());
e = new NotLeaderException(serverMemberId, suggestedLeader, peers);
} else if (replyProto.getExceptionDetailsCase() == NOTREPLICATEDEXCEPTION) {
final NotReplicatedExceptionProto nre = replyProto.getNotReplicatedException();
e = new NotReplicatedException(nre.getCallId(), nre.getReplication(), nre.getLogIndex());
} else if (replyProto.getExceptionDetailsCase().equals(STATEMACHINEEXCEPTION)) {
e = toStateMachineException(serverMemberId, replyProto.getStateMachineException());
} else if (replyProto.getExceptionDetailsCase().equals(DATASTREAMEXCEPTION)) {
e = ProtoUtils.toThrowable(replyProto.getDataStreamException(), DataStreamException.class);
} else if (replyProto.getExceptionDetailsCase().equals(LEADERNOTREADYEXCEPTION)) {
LeaderNotReadyExceptionProto lnreProto = replyProto.getLeaderNotReadyException();
e = new LeaderNotReadyException(ProtoUtils.toRaftGroupMemberId(lnreProto.getServerId()));
} else if (replyProto.getExceptionDetailsCase().equals(ALREADYCLOSEDEXCEPTION)) {
e = toAlreadyClosedException(replyProto.getAlreadyClosedException());
} else if (replyProto.getExceptionDetailsCase().equals(LEADERSTEPPINGDOWNEXCEPTION)) {
e = ProtoUtils.toThrowable(replyProto.getLeaderSteppingDownException(), LeaderSteppingDownException.class);
} else if (replyProto.getExceptionDetailsCase().equals(TRANSFERLEADERSHIPEXCEPTION)) {
e = ProtoUtils.toThrowable(replyProto.getTransferLeadershipException(), TransferLeadershipException.class);
} else {
e = null;
}
return RaftClientReply.newBuilder().setClientId(ClientId.valueOf(rp.getRequestorId())).setServerId(serverMemberId).setCallId(rp.getCallId()).setSuccess(rp.getSuccess()).setMessage(toMessage(replyProto.getMessage())).setException(e).setLogIndex(replyProto.getLogIndex()).setCommitInfos(replyProto.getCommitInfosList()).build();
}
use of org.apache.ratis.protocol.exceptions.NotLeaderException in project incubator-ratis by apache.
the class RaftServerImpl method checkLeaderState.
/**
* @return null if the server is in leader state.
*/
private CompletableFuture<RaftClientReply> checkLeaderState(RaftClientRequest request, CacheEntry entry, boolean isWrite) {
try {
assertGroup(request.getRequestorId(), request.getRaftGroupId());
} catch (GroupMismatchException e) {
return RetryCacheImpl.failWithException(e, entry);
}
if (!getInfo().isLeader()) {
NotLeaderException exception = generateNotLeaderException();
final RaftClientReply reply = newExceptionReply(request, exception);
return RetryCacheImpl.failWithReply(reply, entry);
}
if (!getInfo().isLeaderReady()) {
final CacheEntry cacheEntry = retryCache.getIfPresent(ClientInvocationId.valueOf(request));
if (cacheEntry != null && cacheEntry.isCompletedNormally()) {
return cacheEntry.getReplyFuture();
}
final LeaderNotReadyException lnre = new LeaderNotReadyException(getMemberId());
final RaftClientReply reply = newExceptionReply(request, lnre);
return RetryCacheImpl.failWithReply(reply, entry);
}
if (isWrite && isSteppingDown()) {
final LeaderSteppingDownException lsde = new LeaderSteppingDownException(getMemberId() + " is stepping down");
final RaftClientReply reply = newExceptionReply(request, lsde);
return RetryCacheImpl.failWithReply(reply, entry);
}
return null;
}
use of org.apache.ratis.protocol.exceptions.NotLeaderException in project incubator-ratis by apache.
the class OrderedAsync method sendRequest.
private CompletableFuture<RaftClientReply> sendRequest(PendingOrderedRequest pending) {
final RetryPolicy retryPolicy = client.getRetryPolicy();
final CompletableFuture<RaftClientReply> f;
final RaftClientRequest request;
if (getSlidingWindow((RaftPeerId) null).isFirst(pending.getSeqNum())) {
pending.setFirstRequest();
}
request = pending.newRequest();
LOG.debug("{}: send* {}", client.getId(), request);
f = client.getClientRpc().sendRequestAsync(request);
return f.thenApply(reply -> {
LOG.debug("{}: receive* {}", client.getId(), reply);
getSlidingWindow(request).receiveReply(request.getSlidingWindowEntry().getSeqNum(), reply, this::sendRequestWithRetry);
return reply;
}).exceptionally(e -> {
if (LOG.isTraceEnabled()) {
LOG.trace(client.getId() + ": Failed* " + request, e);
} else {
LOG.debug("{}: Failed* {} with {}", client.getId(), request, e);
}
e = JavaUtils.unwrapCompletionException(e);
if (e instanceof IOException && !(e instanceof GroupMismatchException)) {
pending.incrementExceptionCount(e);
final ClientRetryEvent event = new ClientRetryEvent(request, e, pending);
if (!retryPolicy.handleAttemptFailure(event).shouldRetry()) {
handleAsyncRetryFailure(event);
} else {
if (e instanceof NotLeaderException) {
NotLeaderException nle = (NotLeaderException) e;
client.handleNotLeaderException(request, nle, this::resetSlidingWindow);
} else {
client.handleIOException(request, (IOException) e, null, this::resetSlidingWindow);
}
}
throw new CompletionException(e);
}
failAllAsyncRequests(request, e);
return null;
});
}
use of org.apache.ratis.protocol.exceptions.NotLeaderException in project incubator-ratis by apache.
the class ClientProtoUtils method toRaftClientReplyProto.
static RaftClientReplyProto toRaftClientReplyProto(RaftClientReply reply) {
final RaftClientReplyProto.Builder b = RaftClientReplyProto.newBuilder();
if (reply != null) {
b.setRpcReply(toRaftRpcReplyProtoBuilder(reply.getClientId().toByteString(), reply.getServerId().toByteString(), reply.getRaftGroupId(), reply.getCallId(), reply.isSuccess()));
b.setLogIndex(reply.getLogIndex());
if (reply.getMessage() != null) {
b.setMessage(toClientMessageEntryProtoBuilder(reply.getMessage()));
}
b.addAllCommitInfos(reply.getCommitInfos());
final NotLeaderException nle = reply.getNotLeaderException();
if (nle != null) {
NotLeaderExceptionProto.Builder nleBuilder = NotLeaderExceptionProto.newBuilder();
final RaftPeer suggestedLeader = nle.getSuggestedLeader();
if (suggestedLeader != null) {
nleBuilder.setSuggestedLeader(suggestedLeader.getRaftPeerProto());
}
nleBuilder.addAllPeersInConf(ProtoUtils.toRaftPeerProtos(nle.getPeers()));
b.setNotLeaderException(nleBuilder.build());
}
final NotReplicatedException nre = reply.getNotReplicatedException();
if (nre != null) {
final NotReplicatedExceptionProto.Builder nreBuilder = NotReplicatedExceptionProto.newBuilder().setCallId(nre.getCallId()).setReplication(nre.getRequiredReplication()).setLogIndex(nre.getLogIndex());
b.setNotReplicatedException(nreBuilder);
}
final LeaderNotReadyException lnre = reply.getLeaderNotReadyException();
if (lnre != null) {
LeaderNotReadyExceptionProto.Builder lnreBuilder = LeaderNotReadyExceptionProto.newBuilder().setServerId(ProtoUtils.toRaftGroupMemberIdProtoBuilder(lnre.getServerId()));
b.setLeaderNotReadyException(lnreBuilder);
}
Optional.ofNullable(reply.getStateMachineException()).map(ClientProtoUtils::toStateMachineExceptionProtoBuilder).ifPresent(b::setStateMachineException);
Optional.ofNullable(reply.getDataStreamException()).map(ProtoUtils::toThrowableProto).ifPresent(b::setDataStreamException);
Optional.ofNullable(reply.getAlreadyClosedException()).map(ClientProtoUtils::toAlreadyClosedExceptionProtoBuilder).ifPresent(b::setAlreadyClosedException);
Optional.ofNullable(reply.getLeaderSteppingDownException()).map(ProtoUtils::toThrowableProto).ifPresent(b::setLeaderSteppingDownException);
Optional.ofNullable(reply.getTransferLeadershipException()).map(ProtoUtils::toThrowableProto).ifPresent(b::setTransferLeadershipException);
final RaftClientReplyProto serialized = b.build();
final RaftException e = reply.getException();
if (e != null) {
final RaftClientReply deserialized = toRaftClientReply(serialized);
if (!Optional.ofNullable(deserialized.getException()).map(Object::getClass).filter(e.getClass()::equals).isPresent()) {
throw new AssertionError("Corruption while serializing reply= " + reply + " but serialized=" + serialized + " and deserialized=" + deserialized, e);
}
}
return serialized;
}
return b.build();
}
use of org.apache.ratis.protocol.exceptions.NotLeaderException in project incubator-ratis by apache.
the class UnorderedAsync method sendRequestWithRetry.
static void sendRequestWithRetry(PendingClientRequest pending, RaftClientImpl client) {
final CompletableFuture<RaftClientReply> f = pending.getReplyFuture();
if (f.isDone()) {
return;
}
final RaftClientRequest request = pending.newRequest();
final int attemptCount = pending.getAttemptCount();
final ClientId clientId = client.getId();
LOG.debug("{}: attempt #{} send~ {}", clientId, attemptCount, request);
client.getClientRpc().sendRequestAsyncUnordered(request).whenCompleteAsync((reply, e) -> {
try {
LOG.debug("{}: attempt #{} receive~ {}", clientId, attemptCount, reply);
final RaftException replyException = reply != null ? reply.getException() : null;
reply = client.handleLeaderException(request, reply);
if (reply != null) {
client.handleReply(request, reply);
f.complete(reply);
return;
}
final Throwable cause = replyException != null ? replyException : e;
pending.incrementExceptionCount(cause);
final ClientRetryEvent event = new ClientRetryEvent(request, cause, pending);
RetryPolicy retryPolicy = client.getRetryPolicy();
final RetryPolicy.Action action = retryPolicy.handleAttemptFailure(event);
TimeDuration sleepTime = client.getEffectiveSleepTime(cause, action.getSleepTime());
if (!action.shouldRetry()) {
f.completeExceptionally(client.noMoreRetries(event));
return;
}
if (e != null) {
if (LOG.isTraceEnabled()) {
LOG.trace(clientId + ": attempt #" + attemptCount + " failed~ " + request, e);
} else {
LOG.debug("{}: attempt #{} failed {} with {}", clientId, attemptCount, request, e);
}
e = JavaUtils.unwrapCompletionException(e);
if (e instanceof IOException) {
if (e instanceof NotLeaderException) {
client.handleNotLeaderException(request, (NotLeaderException) e, null);
} else if (e instanceof GroupMismatchException) {
f.completeExceptionally(e);
return;
} else {
client.handleIOException(request, (IOException) e);
}
} else {
if (!client.getClientRpc().handleException(request.getServerId(), e, false)) {
f.completeExceptionally(e);
return;
}
}
}
LOG.debug("schedule retry for attempt #{}, policy={}, request={}", attemptCount, retryPolicy, request);
client.getScheduler().onTimeout(sleepTime, () -> sendRequestWithRetry(pending, client), LOG, () -> clientId + ": Failed~ to retry " + request);
} catch (Exception ex) {
LOG.error(clientId + ": Failed " + request, ex);
f.completeExceptionally(ex);
}
});
}
Aggregations