sync refactor
This commit is contained in:
parent
acfe73ed18
commit
b08cdf2f82
|
@ -510,15 +510,17 @@ void syncNodeUpdateTerm(SSyncNode* pSyncNode, SyncTerm term) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncNodeBecomeFollower(SSyncNode* pSyncNode) {
|
void syncNodeBecomeFollower(SSyncNode* pSyncNode) {
|
||||||
|
// maybe clear leader cache
|
||||||
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||||
pSyncNode->leaderCache = EMPTY_RAFT_ID;
|
pSyncNode->leaderCache = EMPTY_RAFT_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// state change
|
||||||
pSyncNode->state = TAOS_SYNC_STATE_FOLLOWER;
|
pSyncNode->state = TAOS_SYNC_STATE_FOLLOWER;
|
||||||
syncNodeStopHeartbeatTimer(pSyncNode);
|
syncNodeStopHeartbeatTimer(pSyncNode);
|
||||||
|
|
||||||
int32_t electMS = syncUtilElectRandomMS();
|
// reset elect timer
|
||||||
syncNodeRestartElectTimer(pSyncNode, electMS);
|
syncNodeResetElectTimer(pSyncNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLA+ Spec
|
// TLA+ Spec
|
||||||
|
@ -540,19 +542,31 @@ void syncNodeBecomeFollower(SSyncNode* pSyncNode) {
|
||||||
// /\ UNCHANGED <<messages, currentTerm, votedFor, candidateVars, logVars>>
|
// /\ UNCHANGED <<messages, currentTerm, votedFor, candidateVars, logVars>>
|
||||||
//
|
//
|
||||||
void syncNodeBecomeLeader(SSyncNode* pSyncNode) {
|
void syncNodeBecomeLeader(SSyncNode* pSyncNode) {
|
||||||
|
// state change
|
||||||
pSyncNode->state = TAOS_SYNC_STATE_LEADER;
|
pSyncNode->state = TAOS_SYNC_STATE_LEADER;
|
||||||
|
|
||||||
|
// set leader cache
|
||||||
pSyncNode->leaderCache = pSyncNode->myRaftId;
|
pSyncNode->leaderCache = pSyncNode->myRaftId;
|
||||||
|
|
||||||
for (int i = 0; i < pSyncNode->pNextIndex->replicaNum; ++i) {
|
for (int i = 0; i < pSyncNode->pNextIndex->replicaNum; ++i) {
|
||||||
|
// maybe overwrite myself, no harm
|
||||||
|
// just do it!
|
||||||
pSyncNode->pNextIndex->index[i] = pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore) + 1;
|
pSyncNode->pNextIndex->index[i] = pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < pSyncNode->pMatchIndex->replicaNum; ++i) {
|
for (int i = 0; i < pSyncNode->pMatchIndex->replicaNum; ++i) {
|
||||||
|
// maybe overwrite myself, no harm
|
||||||
|
// just do it!
|
||||||
pSyncNode->pMatchIndex->index[i] = SYNC_INDEX_INVALID;
|
pSyncNode->pMatchIndex->index[i] = SYNC_INDEX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stop elect timer
|
||||||
syncNodeStopElectTimer(pSyncNode);
|
syncNodeStopElectTimer(pSyncNode);
|
||||||
|
|
||||||
|
// start heartbeat timer
|
||||||
syncNodeStartHeartbeatTimer(pSyncNode);
|
syncNodeStartHeartbeatTimer(pSyncNode);
|
||||||
|
|
||||||
|
// start replicate right now!
|
||||||
syncNodeReplicate(pSyncNode);
|
syncNodeReplicate(pSyncNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,6 +592,9 @@ void syncNodeCandidate2Follower(SSyncNode* pSyncNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// raft vote --------------
|
// raft vote --------------
|
||||||
|
|
||||||
|
// just called by syncNodeVoteForSelf
|
||||||
|
// need assert
|
||||||
void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) {
|
void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) {
|
||||||
assert(term == pSyncNode->pRaftStore->currentTerm);
|
assert(term == pSyncNode->pRaftStore->currentTerm);
|
||||||
assert(!raftStoreHasVoted(pSyncNode->pRaftStore));
|
assert(!raftStoreHasVoted(pSyncNode->pRaftStore));
|
||||||
|
@ -585,6 +602,7 @@ void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId)
|
||||||
raftStoreVote(pSyncNode->pRaftStore, pRaftId);
|
raftStoreVote(pSyncNode->pRaftStore, pRaftId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// simulate get vote from outside
|
||||||
void syncNodeVoteForSelf(SSyncNode* pSyncNode) {
|
void syncNodeVoteForSelf(SSyncNode* pSyncNode) {
|
||||||
syncNodeVoteForTerm(pSyncNode, pSyncNode->pRaftStore->currentTerm, &(pSyncNode->myRaftId));
|
syncNodeVoteForTerm(pSyncNode, pSyncNode->pRaftStore->currentTerm, &(pSyncNode->myRaftId));
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ cJSON *raftStore2Json(SRaftStore *pRaftStore) {
|
||||||
|
|
||||||
char *raftStore2Str(SRaftStore *pRaftStore) {
|
char *raftStore2Str(SRaftStore *pRaftStore) {
|
||||||
cJSON *pJson = raftStore2Json(pRaftStore);
|
cJSON *pJson = raftStore2Json(pRaftStore);
|
||||||
char *serialized = cJSON_Print(pJson);
|
char * serialized = cJSON_Print(pJson);
|
||||||
cJSON_Delete(pJson);
|
cJSON_Delete(pJson);
|
||||||
return serialized;
|
return serialized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(!(pMsg->term > ths->pRaftStore->currentTerm));
|
||||||
// no need this code, because if I receive reply.term, then I must have sent for that term.
|
// no need this code, because if I receive reply.term, then I must have sent for that term.
|
||||||
// if (pMsg->term > ths->pRaftStore->currentTerm) {
|
// if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||||
// syncNodeUpdateTerm(ths, pMsg->term);
|
// syncNodeUpdateTerm(ths, pMsg->term);
|
||||||
|
@ -52,17 +53,29 @@ int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg)
|
||||||
|
|
||||||
assert(pMsg->term == ths->pRaftStore->currentTerm);
|
assert(pMsg->term == ths->pRaftStore->currentTerm);
|
||||||
|
|
||||||
|
// This tallies votes even when the current state is not Candidate,
|
||||||
|
// but they won't be looked at, so it doesn't matter.
|
||||||
if (ths->state == TAOS_SYNC_STATE_CANDIDATE) {
|
if (ths->state == TAOS_SYNC_STATE_CANDIDATE) {
|
||||||
votesRespondAdd(ths->pVotesRespond, pMsg);
|
votesRespondAdd(ths->pVotesRespond, pMsg);
|
||||||
if (pMsg->voteGranted) {
|
if (pMsg->voteGranted) {
|
||||||
|
// add vote
|
||||||
voteGrantedVote(ths->pVotesGranted, pMsg);
|
voteGrantedVote(ths->pVotesGranted, pMsg);
|
||||||
|
|
||||||
|
// maybe to leader
|
||||||
if (voteGrantedMajority(ths->pVotesGranted)) {
|
if (voteGrantedMajority(ths->pVotesGranted)) {
|
||||||
if (!ths->pVotesGranted->toLeader) {
|
if (!ths->pVotesGranted->toLeader) {
|
||||||
syncNodeCandidate2Leader(ths);
|
syncNodeCandidate2Leader(ths);
|
||||||
|
|
||||||
|
// prevent to leader again!
|
||||||
ths->pVotesGranted->toLeader = true;
|
ths->pVotesGranted->toLeader = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
;
|
||||||
|
// do nothing
|
||||||
|
// UNCHANGED <<votesGranted, voterLog>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue