use of org.apache.ignite.raft.jraft.conf.ConfigurationEntry in project ignite-3 by apache.
the class NodeImpl method init.
@Override
public boolean init(final NodeOptions opts) {
Requires.requireNonNull(opts, "Null node options");
Requires.requireNonNull(opts.getRaftOptions(), "Null raft options");
Requires.requireNonNull(opts.getServiceFactory(), "Null jraft service factory");
this.serviceFactory = opts.getServiceFactory();
this.options = opts;
this.raftOptions = opts.getRaftOptions();
this.metrics = new NodeMetrics(opts.isEnableMetrics());
this.serverId.setPriority(opts.getElectionPriority());
this.electionTimeoutCounter = 0;
if (opts.getReplicationStateListeners() != null)
this.replicatorStateListeners.addAll(opts.getReplicationStateListeners());
if (this.serverId.getIp().equals(Utils.IP_ANY)) {
LOG.error("Node can't start from IP_ANY.");
return false;
}
// Init timers.
initTimers(opts);
// Init pools.
initPools(opts);
this.configManager = new ConfigurationManager();
applyDisruptor = opts.getNodeApplyDisruptor();
applyQueue = applyDisruptor.subscribe(groupId, new LogEntryAndClosureHandler());
if (this.metrics.getMetricRegistry() != null) {
this.metrics.getMetricRegistry().register("jraft-node-impl-disruptor", new DisruptorMetricSet(this.applyQueue));
}
this.fsmCaller = new FSMCallerImpl();
if (!initLogStorage()) {
LOG.error("Node {} initLogStorage failed.", getNodeId());
return false;
}
if (!initMetaStorage()) {
LOG.error("Node {} initMetaStorage failed.", getNodeId());
return false;
}
if (!initFSMCaller(new LogId(0, 0))) {
LOG.error("Node {} initFSMCaller failed.", getNodeId());
return false;
}
this.ballotBox = new BallotBox();
final BallotBoxOptions ballotBoxOpts = new BallotBoxOptions();
ballotBoxOpts.setWaiter(this.fsmCaller);
ballotBoxOpts.setClosureQueue(this.closureQueue);
if (!this.ballotBox.init(ballotBoxOpts)) {
LOG.error("Node {} init ballotBox failed.", getNodeId());
return false;
}
if (!initSnapshotStorage()) {
LOG.error("Node {} initSnapshotStorage failed.", getNodeId());
return false;
}
final Status st = this.logManager.checkConsistency();
if (!st.isOk()) {
LOG.error("Node {} is initialized with inconsistent log, status={}.", getNodeId(), st);
return false;
}
this.conf = new ConfigurationEntry();
this.conf.setId(new LogId());
// if have log using conf in log, else using conf in options
if (this.logManager.getLastLogIndex() > 0) {
checkAndSetConfiguration(false);
} else {
this.conf.setConf(this.options.getInitialConf());
// initially set to max(priority of all nodes)
this.targetPriority = getMaxPriorityOfNodes(this.conf.getConf().getPeers());
}
if (!this.conf.isEmpty()) {
Requires.requireTrue(this.conf.isValid(), "Invalid conf: %s", this.conf);
} else {
LOG.info("Init node {} with empty conf.", this.serverId);
}
this.replicatorGroup = new ReplicatorGroupImpl();
this.rpcClientService = new DefaultRaftClientService();
final ReplicatorGroupOptions rgOpts = new ReplicatorGroupOptions();
rgOpts.setHeartbeatTimeoutMs(heartbeatTimeout(this.options.getElectionTimeoutMs()));
rgOpts.setElectionTimeoutMs(this.options.getElectionTimeoutMs());
rgOpts.setLogManager(this.logManager);
rgOpts.setBallotBox(this.ballotBox);
rgOpts.setNode(this);
rgOpts.setRaftRpcClientService(this.rpcClientService);
rgOpts.setSnapshotStorage(this.snapshotExecutor != null ? this.snapshotExecutor.getSnapshotStorage() : null);
rgOpts.setRaftOptions(this.raftOptions);
rgOpts.setTimerManager(this.options.getScheduler());
// Adds metric registry to RPC service.
this.options.setMetricRegistry(this.metrics.getMetricRegistry());
if (!this.rpcClientService.init(this.options)) {
LOG.error("Fail to init rpc service.");
return false;
}
this.replicatorGroup.init(new NodeId(this.groupId, this.serverId), rgOpts);
this.readOnlyService = new ReadOnlyServiceImpl();
final ReadOnlyServiceOptions rosOpts = new ReadOnlyServiceOptions();
rosOpts.setGroupId(groupId);
rosOpts.setFsmCaller(this.fsmCaller);
rosOpts.setNode(this);
rosOpts.setRaftOptions(this.raftOptions);
rosOpts.setReadOnlyServiceDisruptor(opts.getReadOnlyServiceDisruptor());
if (!this.readOnlyService.init(rosOpts)) {
LOG.error("Fail to init readOnlyService.");
return false;
}
// set state to follower
this.state = State.STATE_FOLLOWER;
if (LOG.isInfoEnabled()) {
LOG.info("Node {} init, term={}, lastLogId={}, conf={}, oldConf={}.", getNodeId(), this.currTerm, this.logManager.getLastLogId(false), this.conf.getConf(), this.conf.getOldConf());
}
if (this.snapshotExecutor != null && this.options.getSnapshotIntervalSecs() > 0) {
LOG.debug("Node {} start snapshot timer, term={}.", getNodeId(), this.currTerm);
this.snapshotTimer.start();
}
if (!this.conf.isEmpty()) {
stepDown(this.currTerm, false, new Status());
}
// Now the raft node is started , have to acquire the writeLock to avoid race
// conditions
this.writeLock.lock();
if (this.conf.isStable() && this.conf.getConf().size() == 1 && this.conf.getConf().contains(this.serverId)) {
// The group contains only this server which must be the LEADER, trigger
// the timer immediately.
electSelf();
} else {
this.writeLock.unlock();
}
return true;
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationEntry in project ignite-3 by apache.
the class FSMCallerImpl method doSnapshotSave.
private void doSnapshotSave(final SaveSnapshotClosure done) {
Requires.requireNonNull(done, "SaveSnapshotClosure is null");
final long lastAppliedIndex = this.lastAppliedIndex.get();
final ConfigurationEntry confEntry = this.logManager.getConfiguration(lastAppliedIndex);
if (confEntry == null || confEntry.isEmpty()) {
LOG.error("Empty conf entry for lastAppliedIndex={}", lastAppliedIndex);
Utils.runClosureInThread(this.node.getOptions().getCommonExecutor(), done, new Status(RaftError.EINVAL, "Empty conf entry for lastAppliedIndex=%s", lastAppliedIndex));
return;
}
SnapshotMetaBuilder metaBuilder = msgFactory.snapshotMeta().lastIncludedIndex(lastAppliedIndex).lastIncludedTerm(this.lastAppliedTerm).peersList(confEntry.getConf().getPeers().stream().map(Object::toString).collect(toList())).learnersList(confEntry.getConf().getLearners().stream().map(Object::toString).collect(toList()));
if (confEntry.getOldConf() != null) {
metaBuilder.oldPeersList(confEntry.getOldConf().getPeers().stream().map(Object::toString).collect(toList())).oldLearnersList(confEntry.getOldConf().getLearners().stream().map(Object::toString).collect(toList()));
}
final SnapshotWriter writer = done.start(metaBuilder.build());
if (writer == null) {
done.run(new Status(RaftError.EINVAL, "snapshot_storage create SnapshotWriter failed"));
return;
}
this.fsm.onSnapshotSave(writer, done);
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationEntry in project ignite-3 by apache.
the class ReplicatorGroupTest method testFindTheNextCandidateWithPriority1.
@Test
public void testFindTheNextCandidateWithPriority1() {
final PeerId p1 = new PeerId("localhost", 18881, 0, 60);
final PeerId p2 = new PeerId("localhost", 18882, 0, 80);
final PeerId p3 = new PeerId("localhost", 18883, 0, 100);
Mockito.when(this.rpcService.connect(p1.getEndpoint())).thenReturn(true);
Mockito.when(this.rpcService.connect(p2.getEndpoint())).thenReturn(true);
Mockito.when(this.rpcService.connect(p3.getEndpoint())).thenReturn(true);
this.replicatorGroup.resetTerm(1);
this.replicatorGroup.addReplicator(p1);
this.replicatorGroup.addReplicator(p2);
this.replicatorGroup.addReplicator(p3);
final ConfigurationEntry conf = new ConfigurationEntry();
conf.setConf(new Configuration(Arrays.asList(p1, p2, p3)));
final PeerId p = this.replicatorGroup.findTheNextCandidate(conf);
assertEquals(p3, p);
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationEntry in project ignite-3 by apache.
the class ReplicatorGroupTest method testFindTheNextCandidateWithPriority2.
@Test
public void testFindTheNextCandidateWithPriority2() {
final PeerId p1 = new PeerId("localhost", 18881, 0, 0);
final PeerId p2 = new PeerId("localhost", 18882, 0, 0);
final PeerId p3 = new PeerId("localhost", 18883, 0, -1);
Mockito.when(this.rpcService.connect(p1.getEndpoint())).thenReturn(true);
Mockito.when(this.rpcService.connect(p2.getEndpoint())).thenReturn(true);
Mockito.when(this.rpcService.connect(p3.getEndpoint())).thenReturn(true);
this.replicatorGroup.resetTerm(1);
this.replicatorGroup.addReplicator(p1);
this.replicatorGroup.addReplicator(p2);
this.replicatorGroup.addReplicator(p3);
final ConfigurationEntry conf = new ConfigurationEntry();
conf.setConf(new Configuration(Arrays.asList(p1, p2, p3)));
final PeerId p = this.replicatorGroup.findTheNextCandidate(conf);
assertEquals(p3, p);
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationEntry in project ignite-3 by apache.
the class LogManagerImpl method setSnapshot.
@Override
public void setSnapshot(final SnapshotMeta meta) {
LOG.debug("set snapshot: {}.", meta);
this.writeLock.lock();
try {
if (meta.lastIncludedIndex() <= this.lastSnapshotId.getIndex()) {
return;
}
final Configuration conf = confFromMeta(meta);
final Configuration oldConf = oldConfFromMeta(meta);
final ConfigurationEntry entry = new ConfigurationEntry(new LogId(meta.lastIncludedIndex(), meta.lastIncludedTerm()), conf, oldConf);
this.configManager.setSnapshot(entry);
final long term = unsafeGetTerm(meta.lastIncludedIndex());
final long savedLastSnapshotIndex = this.lastSnapshotId.getIndex();
this.lastSnapshotId.setIndex(meta.lastIncludedIndex());
this.lastSnapshotId.setTerm(meta.lastIncludedTerm());
if (this.lastSnapshotId.compareTo(this.appliedId) > 0) {
this.appliedId = this.lastSnapshotId.copy();
}
if (term == 0) {
// last_included_index is larger than last_index
// FIXME: what if last_included_index is less than first_index?
truncatePrefix(meta.lastIncludedIndex() + 1);
} else if (term == meta.lastIncludedTerm()) {
// TODO if there are still be need? TODO asch
if (savedLastSnapshotIndex > 0) {
truncatePrefix(savedLastSnapshotIndex + 1);
}
} else {
if (!reset(meta.lastIncludedIndex() + 1)) {
LOG.warn("Reset log manager failed, nextLogIndex={}.", meta.lastIncludedIndex() + 1);
}
}
} finally {
this.writeLock.unlock();
}
}
Aggregations