use of org.apache.ignite.raft.jraft.error.RaftException in project ignite-3 by apache.
the class FSMCallerImpl method doSnapshotLoad.
private void doSnapshotLoad(final LoadSnapshotClosure done) {
Requires.requireNonNull(done, "LoadSnapshotClosure is null");
final SnapshotReader reader = done.start();
if (reader == null) {
done.run(new Status(RaftError.EINVAL, "open SnapshotReader failed"));
return;
}
final RaftOutter.SnapshotMeta meta = reader.load();
if (meta == null) {
done.run(new Status(RaftError.EINVAL, "SnapshotReader load meta failed"));
if (reader.getRaftError() == RaftError.EIO) {
final RaftException err = new RaftException(ErrorType.ERROR_TYPE_SNAPSHOT, RaftError.EIO, "Fail to load snapshot meta");
setError(err);
}
return;
}
final LogId lastAppliedId = new LogId(this.lastAppliedIndex.get(), this.lastAppliedTerm);
final LogId snapshotId = new LogId(meta.lastIncludedIndex(), meta.lastIncludedTerm());
if (lastAppliedId.compareTo(snapshotId) > 0) {
done.run(new Status(RaftError.ESTALE, "Loading a stale snapshot last_applied_index=%d last_applied_term=%d snapshot_index=%d snapshot_term=%d", lastAppliedId.getIndex(), lastAppliedId.getTerm(), snapshotId.getIndex(), snapshotId.getTerm()));
return;
}
if (!this.fsm.onSnapshotLoad(reader)) {
done.run(new Status(-1, "StateMachine onSnapshotLoad failed"));
final RaftException e = new RaftException(ErrorType.ERROR_TYPE_STATE_MACHINE, RaftError.ESTATEMACHINE, "StateMachine onSnapshotLoad failed");
setError(e);
return;
}
if (meta.oldPeersList() == null) {
// Joint stage is not supposed to be noticeable by end users.
final Configuration conf = new Configuration();
if (meta.peersList() != null) {
for (String metaPeer : meta.peersList()) {
final PeerId peer = new PeerId();
Requires.requireTrue(peer.parse(metaPeer), "Parse peer failed");
conf.addPeer(peer);
}
}
this.fsm.onConfigurationCommitted(conf);
}
this.lastAppliedIndex.set(meta.lastIncludedIndex());
this.lastAppliedTerm = meta.lastIncludedTerm();
done.run(Status.OK());
}
use of org.apache.ignite.raft.jraft.error.RaftException in project ignite-3 by apache.
the class Replicator method installSnapshot.
void installSnapshot() {
if (this.state == State.Snapshot) {
LOG.warn("Replicator {} is installing snapshot, ignore the new request.", this.options.getPeerId());
this.id.unlock();
return;
}
boolean doUnlock = true;
try {
Requires.requireTrue(this.reader == null, "Replicator %s already has a snapshot reader, current state is %s", this.options.getPeerId(), this.state);
this.reader = this.options.getSnapshotStorage().open();
if (this.reader == null) {
final NodeImpl node = this.options.getNode();
final RaftException error = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_SNAPSHOT);
error.setStatus(new Status(RaftError.EIO, "Fail to open snapshot"));
this.id.unlock();
doUnlock = false;
node.onError(error);
return;
}
final String uri = this.reader.generateURIForCopy();
if (uri == null) {
final NodeImpl node = this.options.getNode();
final RaftException error = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_SNAPSHOT);
error.setStatus(new Status(RaftError.EIO, "Fail to generate uri for snapshot reader"));
releaseReader();
this.id.unlock();
doUnlock = false;
node.onError(error);
return;
}
final RaftOutter.SnapshotMeta meta = this.reader.load();
if (meta == null) {
final String snapshotPath = this.reader.getPath();
final NodeImpl node = this.options.getNode();
final RaftException error = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_SNAPSHOT);
error.setStatus(new Status(RaftError.EIO, "Fail to load meta from %s", snapshotPath));
releaseReader();
this.id.unlock();
doUnlock = false;
node.onError(error);
return;
}
final InstallSnapshotRequest request = raftOptions.getRaftMessagesFactory().installSnapshotRequest().term(options.getTerm()).groupId(options.getGroupId()).serverId(options.getServerId().toString()).peerId(options.getPeerId().toString()).meta(meta).uri(uri).build();
this.statInfo.runningState = RunningState.INSTALLING_SNAPSHOT;
this.statInfo.lastLogIncluded = meta.lastIncludedIndex();
this.statInfo.lastTermIncluded = meta.lastIncludedTerm();
this.state = State.Snapshot;
// noinspection NonAtomicOperationOnVolatileField
this.installSnapshotCounter++;
final long monotonicSendTimeMs = Utils.monotonicMs();
final int stateVersion = this.version;
final int seq = getAndIncrementReqSeq();
final Future<Message> rpcFuture = this.rpcService.installSnapshot(this.options.getPeerId().getEndpoint(), request, new RpcResponseClosureAdapter<InstallSnapshotResponse>() {
@Override
public void run(final Status status) {
onRpcReturned(Replicator.this.id, RequestType.Snapshot, status, request, getResponse(), seq, stateVersion, monotonicSendTimeMs);
}
});
addInflight(RequestType.Snapshot, this.nextIndex, 0, 0, seq, rpcFuture);
} finally {
if (doUnlock) {
this.id.unlock();
}
}
}
use of org.apache.ignite.raft.jraft.error.RaftException in project ignite-3 by apache.
the class SnapshotExecutorImpl method reportError.
private void reportError(final int errCode, final String fmt, final Object... args) {
final RaftException error = new RaftException(ErrorType.ERROR_TYPE_SNAPSHOT);
error.setStatus(new Status(errCode, fmt, args));
this.fsmCaller.onError(error);
}
use of org.apache.ignite.raft.jraft.error.RaftException in project ignite-3 by apache.
the class FSMCallerImpl method init.
@Override
public boolean init(final FSMCallerOptions opts) {
this.groupId = opts.getGroupId();
this.logManager = opts.getLogManager();
this.fsm = opts.getFsm();
this.closureQueue = opts.getClosureQueue();
this.afterShutdown = opts.getAfterShutdown();
this.node = opts.getNode();
this.nodeMetrics = this.node.getNodeMetrics();
this.lastAppliedIndex.set(opts.getBootstrapId().getIndex());
notifyLastAppliedIndexUpdated(this.lastAppliedIndex.get());
this.lastAppliedTerm = opts.getBootstrapId().getTerm();
disruptor = opts.getfSMCallerExecutorDisruptor();
taskQueue = disruptor.subscribe(groupId, new ApplyTaskHandler());
if (this.nodeMetrics.getMetricRegistry() != null) {
this.nodeMetrics.getMetricRegistry().register("jraft-fsm-caller-disruptor", new DisruptorMetricSet(this.taskQueue));
}
this.error = new RaftException(ErrorType.ERROR_TYPE_NONE);
this.msgFactory = opts.getRaftMessagesFactory();
LOG.info("Starts FSMCaller successfully.");
return true;
}
use of org.apache.ignite.raft.jraft.error.RaftException in project ignite-3 by apache.
the class ItNodeTest method testAppendEntriesWhenFollowerIsInErrorState.
@Test
public void testAppendEntriesWhenFollowerIsInErrorState() throws Exception {
// start five nodes
List<PeerId> peers = TestUtils.generatePeers(5);
cluster = new TestCluster("unitest", dataPath, peers, ELECTION_TIMEOUT_MILLIS, testInfo);
for (PeerId peer : peers) assertTrue(cluster.start(peer.getEndpoint()));
cluster.waitLeader();
Node oldLeader = cluster.getLeader();
assertNotNull(oldLeader);
// apply something
sendTestTaskAndWait(oldLeader);
// set one follower into error state
List<Node> followers = cluster.getFollowers();
assertEquals(4, followers.size());
Node errorNode = followers.get(0);
PeerId errorPeer = errorNode.getNodeId().getPeerId().copy();
Endpoint errorFollowerAddr = errorPeer.getEndpoint();
LOG.info("Set follower {} into error state", errorNode);
((NodeImpl) errorNode).onError(new RaftException(EnumOutter.ErrorType.ERROR_TYPE_STATE_MACHINE, new Status(-1, "Follower has something wrong.")));
// increase term by stopping leader and electing a new leader again
Endpoint oldLeaderAddr = oldLeader.getNodeId().getPeerId().getEndpoint().copy();
assertTrue(cluster.stop(oldLeaderAddr));
cluster.waitLeader();
Node leader = cluster.getLeader();
assertNotNull(leader);
LOG.info("Elect a new leader {}", leader);
// apply something again
sendTestTaskAndWait(leader, 10, RaftError.SUCCESS);
// stop error follower
Thread.sleep(20);
LOG.info("Stop error follower {}", errorNode);
assertTrue(cluster.stop(errorFollowerAddr));
// restart error and old leader
LOG.info("Restart error follower {} and old leader {}", errorFollowerAddr, oldLeaderAddr);
assertTrue(cluster.start(errorFollowerAddr));
assertTrue(cluster.start(oldLeaderAddr));
cluster.ensureSame();
assertEquals(5, cluster.getFsms().size());
for (MockStateMachine fsm : cluster.getFsms()) assertEquals(20, fsm.getLogs().size());
}
Aggregations