use of org.apache.ratis.protocol.exceptions.StateMachineException in project incubator-ratis by apache.
the class RaftServerImpl method replyPendingRequest.
/**
* The log has been submitted to the state machine. Use the future to update
* the pending requests and retry cache.
* @param logEntry the log entry that has been submitted to the state machine
* @param stateMachineFuture the future returned by the state machine
* from which we will get transaction result later
*/
private CompletableFuture<Message> replyPendingRequest(LogEntryProto logEntry, CompletableFuture<Message> stateMachineFuture) {
Preconditions.assertTrue(logEntry.hasStateMachineLogEntry());
final ClientInvocationId invocationId = ClientInvocationId.valueOf(logEntry.getStateMachineLogEntry());
// update the retry cache
final CacheEntry cacheEntry = retryCache.getOrCreateEntry(invocationId);
if (getInfo().isLeader()) {
Preconditions.assertTrue(cacheEntry != null && !cacheEntry.isCompletedNormally(), "retry cache entry should be pending: %s", cacheEntry);
}
if (cacheEntry.isFailed()) {
retryCache.refreshEntry(new CacheEntry(cacheEntry.getKey()));
}
final long logIndex = logEntry.getIndex();
return stateMachineFuture.whenComplete((reply, exception) -> {
final RaftClientReply.Builder b = newReplyBuilder(invocationId, logIndex);
final RaftClientReply r;
if (exception == null) {
r = b.setSuccess().setMessage(reply).build();
} else {
// the exception is coming from the state machine. wrap it into the
// reply as a StateMachineException
final StateMachineException e = new StateMachineException(getMemberId(), exception);
r = b.setException(e).build();
}
// update pending request
role.getLeaderState().ifPresent(leader -> leader.replyPendingRequest(logIndex, r));
cacheEntry.updateResult(r);
});
}
use of org.apache.ratis.protocol.exceptions.StateMachineException in project incubator-ratis by apache.
the class SimpleStateMachine4Testing method query.
/**
* Query the n-th log entry.
* @param request an index represented in a UTF-8 String, or an empty message.
* @return a completed future of the n-th log entry,
* where n is the last applied index if the request is empty,
* otherwise, n is the index represented in the request.
*/
@Override
public CompletableFuture<Message> query(Message request) {
final String string = request.getContent().toStringUtf8();
Exception exception;
try {
LOG.info("query " + string);
final LogEntryProto entry = dataMap.get(string);
if (entry != null) {
return CompletableFuture.completedFuture(Message.valueOf(entry.toByteString()));
}
exception = new IndexOutOfBoundsException(getId() + ": LogEntry not found for query " + string);
} catch (Exception e) {
LOG.warn("Failed request " + request, e);
exception = e;
}
return JavaUtils.completeExceptionally(new StateMachineException("Failed request " + request, exception));
}
use of org.apache.ratis.protocol.exceptions.StateMachineException in project incubator-ratis by apache.
the class RaftStateMachineExceptionTests method runTestHandleStateMachineException.
private void runTestHandleStateMachineException(CLUSTER cluster) throws Exception {
RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
try (final RaftClient client = cluster.createClient(leaderId)) {
client.io().send(new RaftTestUtil.SimpleMessage("m"));
fail("Exception expected");
} catch (StateMachineException e) {
e.printStackTrace();
Assert.assertTrue(e.getCause().getMessage().contains("Fake Exception"));
}
cluster.shutdown();
}
Aggregations