public override RaftEventResult ReceiveAppendEntries(AppendEntriesRPC <T> appendEntries) { //Reply false if term from append entires < currentTerm (§5.1) if (appendEntries.LeaderTerm < CurrentTerm) { var falseResponse = new AppendEntriesResponse(CurrentTerm, Node.Id, false); return(RaftEventResult.ReplyMessage(falseResponse).SetTimer(Node.RaftSettings.FollowerTimeoutFrom, Node.RaftSettings.FollowerTimeoutTo)); } CurrentTerm = appendEntries.LeaderTerm; //if (appendEntries.LogEntries != null) // for (int i = 0; i < appendEntries.LogEntries.Count; i++) // { // if (appendEntries.LogEntries[i].CommitIndex > Node.Log.Count) // { // Node.Log.Add(appendEntries.LogEntries[i]); // Node.CurrentIndex = appendEntries.LogEntries[i].CommitIndex; // } // } var aeResponse = new AppendEntriesResponse(CurrentTerm, Node.Id, true); return(RaftEventResult.ReplyMessage(aeResponse).SetTimer(Node.RaftSettings.FollowerTimeoutFrom, Node.RaftSettings.FollowerTimeoutTo)); }
public override RaftEventResult ReceiveAppendEntries(AppendEntriesRPC <T> appendEntries) { if (appendEntries.LeaderTerm >= CurrentTerm) { return(Node.TranslateToState(RaftNodeState.Follower, appendEntries)); } return(RaftEventResult.Empty); }
RaftEventResult BroadcastAppendEntries() { Node.RaftEventListener.OnAppendEntries(); var appendEntriesMessage = new AppendEntriesRPC <T>(Node.PersistedState.CurrentTerm, Node.Id); appendEntriesMessage.LeaderCommit = Node.CurrentIndex; //for (int i=Node.CurrentIndex; i < Node.Log.Count; i++) //{ // if (appendEntriesMessage.LogEntries == null) // appendEntriesMessage.LogEntries = new List<LogEntry<T>>(); // appendEntriesMessage.LogEntries.Add(Node.Log[i]); //} return(RaftEventResult.BroadcastMessage(appendEntriesMessage).SetTimer(Node.RaftSettings.LeaderTimeoutFrom, Node.RaftSettings.LeaderTimeoutTo)); }
/// <summary> /// Gets the next <see cref="AppendEntries{T}"/> message to be sent. /// </summary> /// <param name="log">Entry log to keep in synchronization. /// </param> /// <returns> /// The message to be send, null if none. /// </returns> public AppendEntriesRPC <T> GetAppendEntries(IList <LogEntry <T> > log, int leaderTerm, string leaderId) { // if we are waiting for an answer and delay is not elapsed // we do nothing if (this.flyingTransaction) { return(null); } var entriesToSend = Math.Max( 0, Math.Min(MaxBatch, log.Count - this.minSynchronizedIndex - 1)); if (entriesToSend == 0 && !this.DelayElapsed) { return(null); } this.flyingTransaction = true; var message = new AppendEntriesRPC <T>(leaderTerm, leaderId) { PrevLogIndex = this.minSynchronizedIndex, PrevLogTerm = this.minSynchronizedIndex < 0 ? -1 : log[this.minSynchronizedIndex].Term, LogEntries = new List <LogEntry <T> >() }; var offset = this.minSynchronizedIndex + 1; for (var i = 0; i < entriesToSend; i++) { message.LogEntries[i] = log[i + offset]; } this.lastSentIndex = offset + entriesToSend - 1; this.lastSentMessageTime = DateTime.Now; return(message); }
public abstract RaftEventResult ReceiveAppendEntries(AppendEntriesRPC <T> appendEntries);