示例#1
0
文件: Server.cs 项目: falps/Rafty
        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());
        }
示例#2
0
        private void ResetLeaderState()
        {
            NextIndex.Clear();
            MatchIndex.Clear();

            Cluster.GetNodeIdsExcept(NodeId).ForEach(x => {
                NextIndex[x]  = Log.Count;
                MatchIndex[x] = 0;
            });
        }
示例#3
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);
        }
示例#4
0
    public string GetFullMatchScore(string gameCode)
    {
        switch (gameCode)
        {
        case "BJDC":
            return(MatchIndex.ToString());

        case "JCZQ":
        case "JCLQ":
            return(MatchIdentity);

        default:
            throw new ArgumentException("获取比赛编号,不支持的彩种 - " + gameCode);
        }
    }
示例#5
0
 public void ResetLeaderState()
 {
     NextIndex.Clear();
     MatchIndex.Clear();
 }
示例#6
0
文件: Server.cs 项目: falps/Rafty
        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);
                    }
                }
            }
        }
示例#7
0
 public PeerState(IPeer peer, MatchIndex matchIndex, NextIndex nextIndex)
 {
     Peer       = peer;
     MatchIndex = matchIndex;
     NextIndex  = nextIndex;
 }
示例#8
0
 public void UpdateMatchIndex(int indexOfHighestKnownReplicatedLog)
 {
     MatchIndex = new MatchIndex(Peer, indexOfHighestKnownReplicatedLog);
 }