use of org.apache.ratis.server.leader.FollowerInfo in project incubator-ratis by apache.
the class LeaderStateImpl method addSenders.
Collection<LogAppender> addSenders(Collection<RaftPeer> newPeers, long nextIndex, boolean attendVote) {
final Timestamp t = Timestamp.currentTime().addTimeMs(-server.getMaxTimeoutMs());
final List<LogAppender> newAppenders = newPeers.stream().map(peer -> {
final FollowerInfo f = new FollowerInfoImpl(server.getMemberId(), peer, t, nextIndex, attendVote);
LogAppender logAppender = server.newLogAppender(this, f);
peerIdFollowerInfoMap.put(peer.getId(), f);
raftServerMetrics.addFollower(peer.getId());
logAppenderMetrics.addFollowerGauges(peer.getId(), f::getNextIndex, f::getMatchIndex, f::getLastRpcTime);
return logAppender;
}).collect(Collectors.toList());
senders.addAll(newAppenders);
return newAppenders;
}
use of org.apache.ratis.server.leader.FollowerInfo in project incubator-ratis by apache.
the class LeaderStateImpl method getFollowerInfos.
private List<FollowerInfo> getFollowerInfos(List<RaftPeerId> followerIDs) {
List<FollowerInfo> followerInfos = new ArrayList<>();
for (int i = 0; i < followerIDs.size(); i++) {
RaftPeerId id = followerIDs.get(i);
if (!peerIdFollowerInfoMap.containsKey(id)) {
throw new IllegalArgumentException("RaftPeerId:" + id + " not in peerIdFollowerInfoMap of leader:" + server.getMemberId());
}
followerInfos.add(peerIdFollowerInfoMap.get(id));
}
return followerInfos;
}
use of org.apache.ratis.server.leader.FollowerInfo in project incubator-ratis by apache.
the class LeaderStateImpl method updateFollowerCommitInfos.
void updateFollowerCommitInfos(CommitInfoCache cache, List<CommitInfoProto> protos) {
for (LogAppender sender : senders.getSenders()) {
FollowerInfo info = sender.getFollower();
protos.add(cache.update(info.getPeer(), info.getCommitIndex()));
}
}
use of org.apache.ratis.server.leader.FollowerInfo in project incubator-ratis by apache.
the class LeaderStateImpl method yieldLeaderToHigherPriorityPeer.
private void yieldLeaderToHigherPriorityPeer() {
if (!server.getInfo().isLeader()) {
return;
}
final RaftConfigurationImpl conf = server.getRaftConf();
final RaftPeer leader = conf.getPeer(server.getId());
if (leader == null) {
LOG.error("{} the leader {} is not in the conf {}", this, server.getId(), conf);
return;
}
int leaderPriority = leader.getPriority();
for (LogAppender logAppender : senders.getSenders()) {
final FollowerInfo followerInfo = logAppender.getFollower();
final RaftPeerId followerID = followerInfo.getPeer().getId();
final RaftPeer follower = conf.getPeer(followerID);
if (follower == null) {
LOG.error("{} the follower {} is not in the conf {}", this, server.getId(), conf);
continue;
}
final int followerPriority = follower.getPriority();
if (followerPriority <= leaderPriority) {
continue;
}
final TermIndex leaderLastEntry = server.getState().getLastEntry();
if (leaderLastEntry == null) {
LOG.info("{} send StartLeaderElectionRequest to follower:{} on term:{} because follower's priority:{} " + "is higher than leader's:{} and leader's lastEntry is null", this, followerID, currentTerm, followerPriority, leaderPriority);
sendStartLeaderElectionToHigherPriorityPeer(followerID, null);
return;
}
if (followerInfo.getMatchIndex() >= leaderLastEntry.getIndex()) {
LOG.info("{} send StartLeaderElectionRequest to follower:{} on term:{} because follower's priority:{} " + "is higher than leader's:{} and follower's lastEntry index:{} catch up with leader's:{}", this, followerID, currentTerm, followerPriority, leaderPriority, followerInfo.getMatchIndex(), leaderLastEntry.getIndex());
sendStartLeaderElectionToHigherPriorityPeer(followerID, leaderLastEntry);
return;
}
}
}
use of org.apache.ratis.server.leader.FollowerInfo in project incubator-ratis by apache.
the class GrpcLogAppender method shouldNotifyToInstallSnapshot.
/**
* Should the Leader notify the Follower to install the snapshot through
* its own State Machine.
* @return the first available log's start term index
*/
private TermIndex shouldNotifyToInstallSnapshot() {
final FollowerInfo follower = getFollower();
final long leaderNextIndex = getRaftLog().getNextIndex();
final boolean isFollowerBootstrapping = getLeaderState().isFollowerBootstrapping(follower);
final long leaderStartIndex = getRaftLog().getStartIndex();
final TermIndex firstAvailable = Optional.ofNullable(getRaftLog().getTermIndex(leaderStartIndex)).orElseGet(() -> TermIndex.valueOf(getServer().getInfo().getCurrentTerm(), leaderNextIndex));
if (isFollowerBootstrapping && !follower.hasAttemptedToInstallSnapshot()) {
// If the follower is bootstrapping and has not yet installed any snapshot from leader, then the follower should
// be notified to install a snapshot. Every follower should try to install at least one snapshot during
// bootstrapping, if available.
LOG.debug("{}: follower is bootstrapping, notify to install snapshot to {}.", this, firstAvailable);
return firstAvailable;
}
final long followerNextIndex = follower.getNextIndex();
if (followerNextIndex >= leaderNextIndex) {
return null;
}
if (followerNextIndex < leaderStartIndex) {
// State Machine.
return firstAvailable;
} else if (leaderStartIndex == RaftLog.INVALID_LOG_INDEX) {
// Leader has no logs to check from, hence return next index.
return firstAvailable;
}
return null;
}
Aggregations