Beispiel #1
0
        public void EntryReplyMessageRecived(AppendEntryResultMessage m)
        {
            if (_serverIdentifier.Equals(m.From))
                return;

            if (_isDispose) return;

            if (_options.UseLogging)            
                _logger.LogInformation($"Processing {nameof(EntryReplyMessageRecived)} \n\t\t Term {m.Term} \n\t\t Success {m.Success}");
            
            if (!_nodes.Contains(m.From))
            {               
                _nodes.Add(m.From);
            }

            if (m.Term < _election.CurrentTerm) return;

            if (m.Term > _election.CurrentTerm)
            {
                _election.CurrentTerm = m.Term;
                _state?.OnNext(ServerStateType.Follower);
                return;
            }

            var term = _election.CurrentTerm;
            
            if (m.Success)
            {                       
                MatchIndex.AddOrUpdate(m.From, m.LogIndex, (oldKey, oldValue) => m.LogIndex);
            }
            
            NextIndex.AddOrUpdate(m.From, m.LogIndex + 1, (oldKey, oldValue) => m.LogIndex + 1);

            var index = _logReplication.CommitIndex;
            // An entry is committed once a majority of followers acknowledge it...
            if (HasMajorityToCommit(ref index))
            {
                // LogReplication commit index gets moved forward to the index
                // will get replicated out to followers in next heatbeat                
                var logs =_logReplication.ToCommit(index, term);

                foreach (var logEntry in logs)
                {
                    _clientReply.OnNext(new ClientResultMessage()
                    {
                        To = logEntry.From,
                        Granted = true
                    });
                }

                _logReplication.Commit(logs);                    
            }
        }
        public void OnHartbeat(AppendEntryResultMessage m)
        {
            var now = DateTimeOffset.UtcNow;

            // Update node from the which responsed to a appendEntry
            var node = _list.Keys.FirstOrDefault(p => p.Identifier.Equals(m.From));
            if (node != null) _list[node] = now.AddSeconds(10);

            // Remove expired node's
            foreach (var item in _list.Where(item => item.Value < now))
            {
                DateTimeOffset value;
                _list.TryRemove(item.Key, out value);
            }
        }