CompletableFuture<RaftClientReply> processQueryFuture( CompletableFuture<Message> queryFuture, RaftClientRequest request) { return queryFuture.thenApply(r -> new RaftClientReply(request, r, getCommitInfos())) .exceptionally(e -> { e = JavaUtils.unwrapCompletionException(e); if (e instanceof StateMachineException) { return new RaftClientReply(request, (StateMachineException)e, getCommitInfos()); } throw new CompletionException(e); }); }
CompletableFuture<RaftClientReply> processQueryFuture( CompletableFuture<Message> queryFuture, RaftClientRequest request) { return queryFuture.thenApply(r -> new RaftClientReply(request, r, getCommitInfos())) .exceptionally(e -> { e = JavaUtils.unwrapCompletionException(e); if (e instanceof StateMachineException) { return new RaftClientReply(request, (StateMachineException)e, getCommitInfos()); } throw new CompletionException(e); }); }
CompletableFuture<RaftClientReply> addWatchReqeust(RaftClientRequest request) { LOG.debug("{}: addWatchRequest {}", server.getId(), request); return watchRequests.add(request) .thenApply(v -> new RaftClientReply(request, server.getCommitInfos())) .exceptionally(e -> { e = JavaUtils.unwrapCompletionException(e); if (e instanceof NotReplicatedException) { return new RaftClientReply(request, (NotReplicatedException)e, server.getCommitInfos()); } else { throw new CompletionException(e); } }); }
private CompletableFuture<RaftClientReply> watchAsync(RaftClientRequest request) { return role.getLeaderState() .map(ls -> ls.addWatchReqeust(request)) .orElseGet(() -> CompletableFuture.completedFuture( new RaftClientReply(request, generateNotLeaderException(), getCommitInfos()))); }
static <REPLY extends RaftClientReply> REPLY waitForReply( RaftPeerId id, RaftClientRequest request, CompletableFuture<REPLY> future, Function<RaftException, REPLY> exceptionReply) throws IOException { try { return future.get(); } catch (InterruptedException e) { final String s = id + ": Interrupted when waiting for reply, request=" + request; LOG.info(s, e); throw IOUtils.toInterruptedIOException(s, e); } catch (ExecutionException e) { final Throwable cause = e.getCause(); if (cause == null) { throw new IOException(e); } if (cause instanceof NotLeaderException || cause instanceof StateMachineException) { final REPLY reply = exceptionReply.apply((RaftException) cause); if (reply != null) { return reply; } } throw IOUtils.asIOException(cause); } }
void replySetConfiguration() { // we allow the pendingRequest to be null in case that the new leader // commits the new configuration while it has not received the retry // request from the client if (pendingSetConf != null) { // for setConfiguration we do not need to wait for statemachine. send back // reply after it's committed. pendingSetConf.setReply(new RaftClientReply(pendingSetConf.getRequest(), server.getCommitInfos())); pendingSetConf = null; } }
AppendEntriesRequestProto newAppendEntriesRequestProto(RaftPeerId targetId, TermIndex previous, List<LogEntryProto> entries, boolean initializing, long callId) { return ServerProtoUtils.toAppendEntriesRequestProto(server.getId(), targetId, server.getGroupId(), currentTerm, entries, raftLog.getLastCommittedIndex(), initializing, previous, server.getCommitInfos(), callId); }
ServerInformationReply getServerInformation(ServerInformationRequest request) { final RaftGroup group = new RaftGroup(groupId, getRaftConf().getPeers()); return new ServerInformationReply(request, getCommitInfos(), group); }
AppendEntriesRequestProto newAppendEntriesRequestProto(RaftPeerId targetId, TermIndex previous, List<LogEntryProto> entries, boolean initializing, long callId) { return ServerProtoUtils.toAppendEntriesRequestProto(server.getId(), targetId, server.getGroupId(), currentTerm, entries, raftLog.getLastCommittedIndex(), initializing, previous, server.getCommitInfos(), callId); }
void stop() { this.running = false; // do not interrupt event processor since it may be in the middle of logSync senders.forEach(LogAppender::stopAppender); final NotLeaderException nle = server.generateNotLeaderException(); final Collection<CommitInfoProto> commitInfos = server.getCommitInfos(); try { final Collection<TransactionContext> transactions = pendingRequests.sendNotLeaderResponses(nle, commitInfos); server.getStateMachine().notifyNotLeader(transactions); watchRequests.failWatches(nle); } catch (IOException e) { LOG.warn(server.getId() + ": Caught exception in sendNotLeaderResponses", e); } }
GroupInfoReply getGroupInfo(GroupInfoRequest request) { return new GroupInfoReply(request, getRoleInfoProto(), state.getStorage().getStorageDir().hasMetaFile(), getCommitInfos(), getGroup()); }
private CompletableFuture<RaftClientReply> staleReadAsync(RaftClientRequest request) { final long minIndex = request.getType().getStaleRead().getMinIndex(); final long commitIndex = state.getLog().getLastCommittedIndex(); LOG.debug("{}: minIndex={}, commitIndex={}", getId(), minIndex, commitIndex); if (commitIndex < minIndex) { final StaleReadException e = new StaleReadException( "Unable to serve stale-read due to server commit index = " + commitIndex + " < min = " + minIndex); return CompletableFuture.completedFuture( new RaftClientReply(request, new StateMachineException(getId(), e), getCommitInfos())); } return processQueryFuture(getStateMachine().queryStale(request.getMessage(), minIndex), request); }
private CompletableFuture<RaftClientReply> staleReadAsync(RaftClientRequest request) { final long minIndex = request.getType().getStaleRead().getMinIndex(); final long commitIndex = state.getLog().getLastCommittedIndex(); LOG.debug("{}: minIndex={}, commitIndex={}", getId(), minIndex, commitIndex); if (commitIndex < minIndex) { final StaleReadException e = new StaleReadException( "Unable to serve stale-read due to server commit index = " + commitIndex + " < min = " + minIndex); return CompletableFuture.completedFuture( new RaftClientReply(request, new StateMachineException(getId(), e), getCommitInfos())); } return processQueryFuture(getStateMachine().queryStale(request.getMessage(), minIndex), request); }
private CompletableFuture<RaftClientReply> groupAddAsync(GroupManagementRequest request, RaftGroup newGroup) { if (!request.getRaftGroupId().equals(newGroup.getGroupId())) { return JavaUtils.completeExceptionally(new GroupMismatchException( getId() + ": Request group id (" + request.getRaftGroupId() + ") does not match the new group " + newGroup)); } return impls.addNew(newGroup) .thenApplyAsync(newImpl -> { LOG.debug("{}: newImpl = {}", getId(), newImpl); final boolean started = newImpl.start(); Preconditions.assertTrue(started, () -> getId()+ ": failed to start a new impl: " + newImpl); return new RaftClientReply(request, newImpl.getCommitInfos()); }) .whenComplete((_1, throwable) -> { if (throwable != null) { impls.remove(newGroup.getGroupId()); LOG.warn(getId() + ": Failed groupAdd* " + request, throwable); } }); }
RaftClientReply exceptionReply = new RaftClientReply(request, e, getCommitInfos()); cacheEntry.failWithReply(exceptionReply); return CompletableFuture.completedFuture(exceptionReply);
private CompletableFuture<RaftClientReply> groupRemoveAsync( RaftClientRequest request, RaftGroupId groupId, boolean deleteDirectory) { if (!request.getRaftGroupId().equals(groupId)) { return JavaUtils.completeExceptionally(new GroupMismatchException( getId() + ": Request group id (" + request.getRaftGroupId() + ") does not match the given group id " + groupId)); } final CompletableFuture<RaftServerImpl> f = impls.remove(groupId); if (f == null) { return JavaUtils.completeExceptionally(new GroupMismatchException( getId() + ": Group " + groupId + " not found.")); } return f.thenApply(impl -> { final Collection<CommitInfoProto> commitInfos = impl.getCommitInfos(); impl.shutdown(deleteDirectory); return new RaftClientReply(request, commitInfos); }); }
public void failClientRequest(LogEntryProto logEntry) { if (logEntry.getLogEntryBodyCase() == LogEntryProto.LogEntryBodyCase.SMLOGENTRY) { final ClientId clientId = ClientId.valueOf(logEntry.getClientId()); final RetryCache.CacheEntry cacheEntry = getRetryCache().get(clientId, logEntry.getCallId()); if (cacheEntry != null) { final RaftClientReply reply = new RaftClientReply(clientId, getId(), getGroupId(), logEntry.getCallId(), false, null, generateNotLeaderException(), getCommitInfos()); cacheEntry.failWithReply(reply); } } }
public void failClientRequest(LogEntryProto logEntry) { if (logEntry.hasStateMachineLogEntry()) { final StateMachineLogEntryProto smLog = logEntry.getStateMachineLogEntry(); final ClientId clientId = ClientId.valueOf(smLog.getClientId()); final long callId = smLog.getCallId(); final RetryCache.CacheEntry cacheEntry = getRetryCache().get(clientId, callId); if (cacheEntry != null) { final RaftClientReply reply = new RaftClientReply(clientId, getId(), getGroupId(), callId, false, null, generateNotLeaderException(), logEntry.getIndex(), getCommitInfos()); cacheEntry.failWithReply(reply); } } }
/** * @return null if the server is in leader state. */ private CompletableFuture<RaftClientReply> checkLeaderState( RaftClientRequest request, RetryCache.CacheEntry entry) { try { assertGroup(request.getRequestorId(), request.getRaftGroupId()); } catch (GroupMismatchException e) { return RetryCache.failWithException(e, entry); } if (!isLeader()) { NotLeaderException exception = generateNotLeaderException(); final RaftClientReply reply = new RaftClientReply(request, exception, getCommitInfos()); return RetryCache.failWithReply(reply, entry); } final LeaderState leaderState = role.getLeaderState().orElse(null); if (leaderState == null || !leaderState.isReady()) { RetryCache.CacheEntry cacheEntry = retryCache.get(request.getClientId(), request.getCallId()); if (cacheEntry != null && cacheEntry.isCompletedNormally()) { return cacheEntry.getReplyFuture(); } return RetryCache.failWithException(new LeaderNotReadyException(getId()), entry); } return null; }
/** * @return null if the server is in leader state. */ private CompletableFuture<RaftClientReply> checkLeaderState( RaftClientRequest request, RetryCache.CacheEntry entry) { try { assertGroup(request.getRequestorId(), request.getRaftGroupId()); } catch (GroupMismatchException e) { return RetryCache.failWithException(e, entry); } if (!isLeader()) { NotLeaderException exception = generateNotLeaderException(); final RaftClientReply reply = new RaftClientReply(request, exception, getCommitInfos()); return RetryCache.failWithReply(reply, entry); } else if (leaderState == null || !leaderState.isReady()) { RetryCache.CacheEntry cacheEntry = retryCache.get(request.getClientId(), request.getCallId()); if (cacheEntry != null && cacheEntry.isCompletedNormally()) { return cacheEntry.getReplyFuture(); } return RetryCache.failWithException(new LeaderNotReadyException(getId()), entry); } return null; }