void LeaderTimerElapse(object userToken) { try { //Sending signal to all (except self that it is a leader) LeaderHeartbeat heartBeat = null; lock (lock_Operations) { heartBeat = new LeaderHeartbeat() { LeaderTerm = this.NodeTerm, StateLogLatestIndex = NodeStateLog.StateLogId, StateLogLatestTerm = NodeStateLog.StateLogTerm, LastStateLogCommittedIndex = this.NodeStateLog.LastCommittedIndex, LastStateLogCommittedIndexTerm = this.NodeStateLog.LastCommittedIndexTerm }; } //VerbosePrint($"{NodeAddress.NodeAddressId} (Leader)> leader_heartbeat"); this.Sender.SendToAll(eRaftSignalType.LeaderHearthbeat, heartBeat.SerializeBiser(), this.NodeAddress, entitySettings.EntityName, true); } catch (Exception ex) { Log.Log(new WarningLogEntry() { Exception = ex, Method = "Raft.RaftNode.LeaderTimerElapse" }); } }
/// <summary> /// Leader receives accepted Log /// </summary> /// <param name="address"></param> /// <param name="data"></param> void ParseStateLogEntryAccepted(NodeAddress address, byte[] data) { if (this.NodeState != eNodeState.Leader) { return; } StateLogEntryApplied applied = StateLogEntryApplied.BiserDecode(data); var res = this.NodeStateLog.EntryIsAccepted(address, GetMajorityQuantity(), applied); if (res == StateLog.eEntryAcceptanceResult.Committed) { this.VerbosePrint($"{this.NodeAddress.NodeAddressId}> LogEntry {applied.StateLogEntryId} is COMMITTED (answer from {address.NodeAddressId})"); RemoveLeaderLogResendTimer(); //Force heartbeat, to make followers to get faster info about commited elements LeaderHeartbeat heartBeat = new LeaderHeartbeat() { LeaderTerm = this.NodeTerm, StateLogLatestIndex = NodeStateLog.StateLogId, StateLogLatestTerm = NodeStateLog.StateLogTerm, LastStateLogCommittedIndex = this.NodeStateLog.LastCommittedIndex, LastStateLogCommittedIndexTerm = this.NodeStateLog.LastCommittedIndexTerm }; this.Sender.SendToAll(eRaftSignalType.LeaderHearthbeat, heartBeat.SerializeBiser(), this.NodeAddress, entitySettings.EntityName, true); //--------------------------------------- //this.NodeStateLog.RemoveEntryFromDistribution(applied.StateLogEntryId, applied.StateLogEntryTerm); InLogEntrySend = false; ApplyLogEntry(); } }