private void ProcessClientReq() { Console.WriteLine("[Server-{0} :: {1}] is processing a client request ...\n", this.Id, this.CurrentTerm); this.Client = ((Tuple <Machine, Command>) this.Payload).Item1; var newEntry = new Entry(); newEntry.Command = ((Tuple <Machine, Command>) this.Payload).Item2; newEntry.Index = this.Log.Count; newEntry.Term = this.CurrentTerm; this.Log.Clear(); this.Log.Add(newEntry); var appendEntries = new AppendEntriesMessage(); appendEntries.Term = this.CurrentTerm; appendEntries.LeaderId = this.Id; appendEntries.LeaderCommit = this.CommitIndex; if (this.Servers != null) { for (int idx = 0; idx < this.Servers.Count; idx++) { if (idx == this.Id) { continue; } appendEntries.Entries = new List <Entry>(); var nextIndex = this.NextIndex[idx]; if (this.Log.Count - 1 >= nextIndex && nextIndex >= 0) { for (int i = nextIndex; i < this.Log.Count; i++) { appendEntries.Entries.Add(this.Log[i]); } } else { appendEntries.Entries.Add(newEntry); } this.Send(this.Servers[idx], new eAppendEntries(appendEntries)); } } this.Acks.Add(true); }
private void ProcessHeartBeat() { Console.WriteLine("[Server-{0} :: {1}] is sending heartbeats ...\n", this.Id, this.CurrentTerm); if (this.Servers != null) { for (int idx = 0; idx < this.Servers.Count; idx++) { if (idx != this.Id) { var appendEntries = new AppendEntriesMessage(); appendEntries.Term = this.CurrentTerm; appendEntries.LeaderId = this.Id; appendEntries.Entries = new List <Entry>(); this.Send(this.Servers[idx], new eAppendEntries(appendEntries)); } } } }
private void ProcessAppendEntriesAck() { var appendEntriesAck = (AppendEntriesAckMessage)this.Payload; if (appendEntriesAck.Success) { Console.WriteLine("[Server-{0} :: {1}] received a successful append entries ack from " + "server {2} with term {3} ...\n", this.Id, this.CurrentTerm, appendEntriesAck.SenderId, appendEntriesAck.Term); this.NextIndex[appendEntriesAck.SenderId] = this.Log.Count - 1; this.MatchIndex[appendEntriesAck.SenderId] = this.Log.Count - 1; } else { Console.WriteLine("[Server-{0} :: {1}] received an un-successful append entries ack from " + "server {2} with term {3} ...\n", this.Id, this.CurrentTerm, appendEntriesAck.SenderId, appendEntriesAck.Term); this.NextIndex[appendEntriesAck.SenderId] = this.NextIndex[appendEntriesAck.SenderId] - 1; if (this.NextIndex[appendEntriesAck.SenderId] < 0) { this.NextIndex[appendEntriesAck.SenderId] = 0; } if (this.Servers != null && this.Log.Count > 0) { var appendEntries = new AppendEntriesMessage(); appendEntries.Term = this.CurrentTerm; appendEntries.LeaderId = this.Id; appendEntries.LeaderCommit = this.CommitIndex; appendEntries.Entries = new List <Entry>(); var nextIndex = this.NextIndex[appendEntriesAck.SenderId]; if (this.Log.Count - 1 >= nextIndex) { for (int i = nextIndex; i < this.Log.Count; i++) { appendEntries.Entries.Add(this.Log[i]); } } else { appendEntries.Entries.Add(this.Log[this.Log.Count - 1]); } if (nextIndex > 0) { appendEntries.PrevLogIndex = nextIndex - 1; appendEntries.PrevLogTerm = this.Log[nextIndex - 1].Term; } this.Send(this.Servers[appendEntriesAck.SenderId], new eAppendEntries(appendEntries)); } } if (appendEntriesAck.Term > this.CurrentTerm) { this.CurrentTerm = appendEntriesAck.Term; } this.Acks.Add(appendEntriesAck.Success); int ackCounter = 0; foreach (var ack in this.Acks) { if (ack) { ackCounter = ackCounter + 1; } } var majority = (this.Votes.Length / 2) + 1; if (this.Acks.Count == this.Votes.Length && this.Log.Count > 0 && this.Client != null) { if (ackCounter >= majority) { var latestCommand = this.Log[this.Log.Count - 1].Command; if (latestCommand.CommandType == CommandTypes.Add) { this.State = this.State + latestCommand.Value; } else { this.State = this.State - latestCommand.Value; } this.CommitIndex = this.Log.Count - 1; this.Send(this.Client, new eClientReqAck(this.State)); } else { this.Send(this.Client, new eClientReqAck(null)); } } }