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); } }