use of org.apache.ratis.statemachine.TransactionContext in project incubator-ratis by apache.
the class RaftServerImpl method submitClientRequestAsync.
@Override
public CompletableFuture<RaftClientReply> submitClientRequestAsync(RaftClientRequest request) throws IOException {
assertLifeCycleState(RUNNING);
LOG.debug("{}: receive client request({})", getId(), request);
if (request.is(RaftClientRequestProto.TypeCase.STALEREAD)) {
return staleReadAsync(request);
}
// first check the server's leader state
CompletableFuture<RaftClientReply> reply = checkLeaderState(request, null);
if (reply != null) {
return reply;
}
// let the state machine handle read-only request from client
final StateMachine stateMachine = getStateMachine();
if (request.is(RaftClientRequestProto.TypeCase.READ)) {
// See the RAFT paper section 8 (last part)
return processQueryFuture(stateMachine.query(request.getMessage()), request);
}
// query the retry cache
RetryCache.CacheQueryResult previousResult = retryCache.queryCache(request.getClientId(), request.getCallId());
if (previousResult.isRetry()) {
// future
return previousResult.getEntry().getReplyFuture();
}
final RetryCache.CacheEntry cacheEntry = previousResult.getEntry();
// TODO: this client request will not be added to pending requests until
// later which means that any failure in between will leave partial state in
// the state machine. We should call cancelTransaction() for failed requests
TransactionContext context = stateMachine.startTransaction(request);
if (context.getException() != null) {
RaftClientReply exceptionReply = new RaftClientReply(request, new StateMachineException(getId(), context.getException()), getCommitInfos());
cacheEntry.failWithReply(exceptionReply);
return CompletableFuture.completedFuture(exceptionReply);
}
return appendTransaction(request, context, cacheEntry);
}
Aggregations