use of org.apache.ratis.protocol.exceptions.LeaderSteppingDownException 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.LeaderSteppingDownException in project incubator-ratis by apache.
the class BlockingImpl method sendRequestWithRetry.
RaftClientReply sendRequestWithRetry(Supplier<RaftClientRequest> supplier) throws IOException {
RaftClientImpl.PendingClientRequest pending = new RaftClientImpl.PendingClientRequest() {
@Override
public RaftClientRequest newRequestImpl() {
return supplier.get();
}
};
while (true) {
final RaftClientRequest request = pending.newRequest();
IOException ioe = null;
try {
final RaftClientReply reply = sendRequest(request);
if (reply != null) {
return client.handleReply(request, reply);
}
} catch (GroupMismatchException | StateMachineException | TransferLeadershipException | LeaderSteppingDownException | AlreadyClosedException | AlreadyExistsException e) {
throw e;
} catch (IOException e) {
ioe = e;
}
pending.incrementExceptionCount(ioe);
ClientRetryEvent event = new ClientRetryEvent(request, ioe, pending);
final RetryPolicy retryPolicy = client.getRetryPolicy();
final RetryPolicy.Action action = retryPolicy.handleAttemptFailure(event);
TimeDuration sleepTime = client.getEffectiveSleepTime(ioe, action.getSleepTime());
if (!action.shouldRetry()) {
throw (IOException) client.noMoreRetries(event);
}
try {
sleepTime.sleep();
} catch (InterruptedException e) {
throw new InterruptedIOException("retry policy=" + retryPolicy);
}
}
}
use of org.apache.ratis.protocol.exceptions.LeaderSteppingDownException 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.LeaderSteppingDownException in project incubator-ratis by apache.
the class LeaderElectionTests method testTransferLeaderTimeout.
@Test
public void testTransferLeaderTimeout() throws Exception {
try (final MiniRaftCluster cluster = newCluster(3)) {
cluster.start();
final RaftServer.Division leader = waitForLeader(cluster);
try (RaftClient client = cluster.createClient(leader.getId())) {
List<RaftServer.Division> followers = cluster.getFollowers();
Assert.assertEquals(followers.size(), 2);
RaftServer.Division newLeader = followers.get(0);
// isolate new leader, so that transfer leadership will timeout
isolate(cluster, newLeader.getId());
List<RaftPeer> peers = cluster.getPeers();
List<RaftPeer> peersWithNewPriority = getPeersWithPriority(peers, newLeader.getPeer());
RaftClientReply reply = client.admin().setConfiguration(peersWithNewPriority.toArray(new RaftPeer[0]));
Assert.assertTrue(reply.isSuccess());
CompletableFuture<Boolean> transferTimeoutFuture = CompletableFuture.supplyAsync(() -> {
try {
long timeoutMs = 5000;
long start = System.currentTimeMillis();
try {
client.admin().transferLeadership(newLeader.getId(), timeoutMs);
} catch (TransferLeadershipException e) {
long cost = System.currentTimeMillis() - start;
Assert.assertTrue(cost > timeoutMs);
Assert.assertTrue(e.getMessage().contains("Failed to transfer leadership to"));
Assert.assertTrue(e.getMessage().contains("timed out"));
}
return true;
} catch (IOException e) {
return false;
}
});
// before transfer timeout, leader should in steppingDown
JavaUtils.attemptRepeatedly(() -> {
try {
client.io().send(new RaftTestUtil.SimpleMessage("message"));
} catch (LeaderSteppingDownException e) {
Assert.assertTrue(e.getMessage().contains("is stepping down"));
}
return null;
}, 5, TimeDuration.ONE_SECOND, "check leader steppingDown", RaftServer.LOG);
Assert.assertTrue(transferTimeoutFuture.get());
// after transfer timeout, leader should accept request
reply = client.io().send(new RaftTestUtil.SimpleMessage("message"));
Assert.assertTrue(reply.getReplierId().equals(leader.getId().toString()));
Assert.assertTrue(reply.isSuccess());
deIsolate(cluster, newLeader.getId());
}
cluster.shutdown();
}
}
Aggregations