public async Task <SendLeaderCommandResponse> Receive(ICommand command) { if (State is Follower) { await _messageBus.Send(command, LeaderId); } if (State is Leader) { _logger.LogDebug("Server Received Command"); _appendingEntries = true; Log.Add(new Log(CurrentTerm, command)); CommitIndex = Log.Count - 1; var remoteServers = GetRemoteServers(); var tasks = new Task <AppendEntriesResponse> [remoteServers.Count]; for (int i = 0; i < tasks.Length; i++) { var next = NextIndex.FirstOrDefault(x => x.Id == remoteServers[i].Id); if (next == null) { var nextLogIndex = 0; next = new Next(remoteServers[i].Id, nextLogIndex); NextIndex.Add(next); } var match = MatchIndex.FirstOrDefault(x => x.Id == remoteServers[i].Id); if (match == null) { match = new Match(remoteServers[i].Id, 0); MatchIndex.Add(match); } var lastLogIndex = Log.Count > 0 ? Log.Count - 1 : 0; var lastLogTerm = lastLogIndex > 0 ? Log[match.MatchIndex].Term : 0; // If last log index ≥ nextIndex for a follower: send // AppendEntries RPC with log entries starting at nextIndex if (lastLogIndex >= next.NextIndex) { var log = Log[next.NextIndex]; var appendEntries = new AppendEntries(CurrentTerm, Id, match.MatchIndex, lastLogTerm, log, CommitIndex, remoteServers[i].Id); tasks[i] = _messageBus.Send(appendEntries); } } Task.WaitAll(tasks); int counter = 0; foreach (var task in tasks) { _logger.LogDebug($"Processing Append entries counter: {counter}"); _logger.LogDebug($"Processing Append entries result was: {task.Result.Success} counter: {counter}"); await Receive(task.Result); _logger.LogDebug($"Processed Append entries counter: {counter}"); } } return(new SendLeaderCommandResponse()); }
private void ResetLeaderState() { NextIndex.Clear(); MatchIndex.Clear(); Cluster.GetNodeIdsExcept(NodeId).ForEach(x => { NextIndex[x] = Log.Count; MatchIndex[x] = 0; }); }
/// <summary> /// Sirve como la función hash predeterminada. /// </summary> /// <returns>Código hash para el objeto actual.</returns> public int GetMatchHashCode() { int hash = 17; // Un número primo int prime = 31; // Otro número primo. hash = hash * prime + MatchIndex.GetHashCode(); hash = hash * prime + TextValue.GetHashCode(); return(hash); }
public string GetFullMatchScore(string gameCode) { switch (gameCode) { case "BJDC": return(MatchIndex.ToString()); case "JCZQ": case "JCLQ": return(MatchIdentity); default: throw new ArgumentException("获取比赛编号,不支持的彩种 - " + gameCode); } }
public void ResetLeaderState() { NextIndex.Clear(); MatchIndex.Clear(); }
private async Task Receive(AppendEntriesResponse appendEntriesResponse) { if (State is Leader) { // If RPC request or response contains term T > currentTerm: // set currentTerm = T, convert to follower (§5.1) if (appendEntriesResponse.Term > CurrentTerm) { BecomeFollowerAndMatchTerm(appendEntriesResponse.Term, appendEntriesResponse.FollowerId); } // If successful: update nextIndex and matchIndex for // follower (§5.3) if (State is Leader && appendEntriesResponse.Success) { var currentNext = NextIndex.First(x => x.Id == appendEntriesResponse.FollowerId); NextIndex.Remove(currentNext); var nextLogIndex = Log.Count; var next = new Next(appendEntriesResponse.FollowerId, nextLogIndex); NextIndex.Add(next); var currentMatch = MatchIndex.First(x => x.Id == appendEntriesResponse.FollowerId); MatchIndex.Remove(currentMatch); var match = new Match(appendEntriesResponse.FollowerId, currentNext.NextIndex); MatchIndex.Add(match); } if (State is Leader && _appendingEntries && appendEntriesResponse.Success) { CurrentTermAppendEntriesResponse++; if (CurrentTermAppendEntriesResponse >= (_serversInClusterInCluster.Count / 2) + 1) { if ((CommitIndex == 0 && LastApplied == 0) || CommitIndex > LastApplied) { var entry = Log[Log.Count - 1]; LastApplied = Log.Count - 1; await _stateMachine.Apply(entry.Command); } CurrentTermAppendEntriesResponse = 0; _appendingEntries = false; } } // If AppendEntries fails because of log inconsistency: // decrement nextIndex and retry (§5.3) else if (State is Leader && _appendingEntries) { var lastLogIndex = Log.Count - 1; var lastLogTerm = Log[lastLogIndex].Term; var next = NextIndex.First(x => x.Id == appendEntriesResponse.FollowerId); if (lastLogIndex >= next.NextIndex) { var log = Log[next.NextIndex]; var appendEntries = new AppendEntries(CurrentTerm, Id, lastLogIndex, lastLogTerm, log, CommitIndex, appendEntriesResponse.FollowerId); var task = _messageBus.Send(appendEntries); Task.WaitAll(task); await Receive(task.Result); } } } }
public PeerState(IPeer peer, MatchIndex matchIndex, NextIndex nextIndex) { Peer = peer; MatchIndex = matchIndex; NextIndex = nextIndex; }
public void UpdateMatchIndex(int indexOfHighestKnownReplicatedLog) { MatchIndex = new MatchIndex(Peer, indexOfHighestKnownReplicatedLog); }