This commit is contained in:
Raycho Mukelov 2023-10-20 09:31:58 +03:00
parent 98f0683654
commit 7509976cdd
3 changed files with 10 additions and 3 deletions

View File

@ -82,6 +82,7 @@ proc raftNodeStartElection*[SmCommandType, SmStateType](node: RaftNode[SmCommand
return return
if node.state == rnsLeader and not node.hrtBtSuccess: if node.state == rnsLeader and not node.hrtBtSuccess:
raftNodeCancelTimers(node)
debug "Raft Node transition to follower - unsuccsessful heart beat rounds", node_id=node.id debug "Raft Node transition to follower - unsuccsessful heart beat rounds", node_id=node.id
node.state = rnsFollower node.state = rnsFollower
node.currentLeaderId = DefaultUUID node.currentLeaderId = DefaultUUID
@ -89,6 +90,8 @@ proc raftNodeStartElection*[SmCommandType, SmStateType](node: RaftNode[SmCommand
raftNodeScheduleElectionTimeout(node) raftNodeScheduleElectionTimeout(node)
return return
raftNodeScheduleElectionTimeout(node)
while node.votesFuts.len > 0: while node.votesFuts.len > 0:
discard node.votesFuts.pop discard node.votesFuts.pop
@ -127,10 +130,14 @@ proc raftNodeStartElection*[SmCommandType, SmStateType](node: RaftNode[SmCommand
if node.state == rnsCandidate: if node.state == rnsCandidate:
if raftNodeQuorumMin(node): if raftNodeQuorumMin(node):
await cancelAndWait(node.electionTimeoutTimer) await cancelAndWait(node.electionTimeoutTimer)
raftNodeScheduleElectionTimeout(node)
debug "Raft Node transition to leader", node_id=node.id debug "Raft Node transition to leader", node_id=node.id
node.state = rnsLeader # Transition to leader state and send Heart-Beat to establish this node as the cluster leader node.state = rnsLeader # Transition to leader state and send Heart-Beat to establish this node as the cluster leader
raftNodeScheduleElectionTimeout(node)
asyncSpawn raftNodeSendHeartBeat(node) asyncSpawn raftNodeSendHeartBeat(node)
else:
node.state = rnsFollower
node.currentLeaderId = DefaultUUID
node.votedFor = DefaultUUID
proc raftNodeHandleAppendEntries*[SmCommandType, SmStateType](node: RaftNode[SmCommandType, SmStateType], msg: RaftMessage[SmCommandType, SmStateType]): proc raftNodeHandleAppendEntries*[SmCommandType, SmStateType](node: RaftNode[SmCommandType, SmStateType], msg: RaftMessage[SmCommandType, SmStateType]):
RaftMessageResponse[SmCommandType, SmStateType] = RaftMessageResponse[SmCommandType, SmStateType] =

View File

@ -48,7 +48,7 @@ proc basicRaftClusterClientRequest*(cluster: BasicRaftCluster, req: RaftNodeClie
of rncroExecSmCommand: of rncroExecSmCommand:
discard discard
proc basicRaftClusterInit*(nodesIds: seq[RaftNodeId], networkDelay: int=25, electionTimeout: int=150, heartBeatTimeout: int=150, appendEntriesRespTimeout: int=20, votingRespTimeout: int=20, proc basicRaftClusterInit*(nodesIds: seq[RaftNodeId], networkDelay: int=10, electionTimeout: int=150, heartBeatTimeout: int=150, appendEntriesRespTimeout: int=20, votingRespTimeout: int=20,
heartBeatRespTimeout: int=10): BasicRaftCluster = heartBeatRespTimeout: int=10): BasicRaftCluster =
new(result) new(result)
for nodeId in nodesIds: for nodeId in nodesIds:

View File

@ -20,7 +20,7 @@ proc basicClusterElectionMain*() =
test "Basic Raft Cluster Init (5 nodes)": test "Basic Raft Cluster Init (5 nodes)":
for i in 0..4: for i in 0..4:
nodesIds[i] = genUUID() nodesIds[i] = genUUID()
cluster = basicRaftClusterInit(nodesIds, 25, 150, 150, 20, 20, 10) cluster = basicRaftClusterInit(nodesIds, 15, 150, 150, 20, 20, 10)
check cluster != nil check cluster != nil
test "Start Basic Raft Cluster and wait it to converge for a 2 seconds interval (Elect a Leader)": test "Start Basic Raft Cluster and wait it to converge for a 2 seconds interval (Elect a Leader)":