Split long if-elseif into functions

de64
Vitaliy Filippov 2023-09-29 00:39:29 +03:00
parent 1d8dfc861c
commit c96a762ffc
1 changed files with 93 additions and 65 deletions

View File

@ -125,83 +125,111 @@ class TinyRaft extends EventEmitter
{
if (msg.type == VOTE_REQUEST)
{
if (msg.term > this.term && msg.leader)
this.onReceiveVoteRequest(from, msg);
}
else if (msg.type == VOTE)
{
this.onReceiveVote(from, msg);
}
else if (msg.type == PING)
{
this.onReceivePing(from, msg);
}
else if (msg.type == PONG)
{
this.onReceivePong(from, msg);
}
}
onReceiveVoteRequest(from, msg)
{
if (msg.term > this.term && msg.leader)
{
this.leader = msg.leader;
this.term = msg.term;
this.state = CANDIDATE;
this._nextTerm(this.heartbeatTimeout*2 + this.electionTimeout);
this.emit('change', { state: this.state, term: this.term, leader: this.leader });
}
this.send(from, { type: VOTE, term: this.term, leader: this.leader });
}
onReceiveVote(from, msg)
{
if (msg.term != this.term)
{
return;
}
this.voted++;
this.votes[msg.leader] = this.votes[msg.leader] || [];
this.votes[msg.leader].push(from);
const n = this.votes[msg.leader].length;
if (n == 1 + (0 | this.nodes.length/2))
{
if (msg.leader == this.nodeId)
{
this.leader = msg.leader;
this.term = msg.term;
this.state = CANDIDATE;
this._nextTerm(this.heartbeatTimeout*2 + this.electionTimeout);
this.emit('change', { state: this.state, term: this.term, leader: this.leader });
}
this.send(from, { type: VOTE, term: this.term, leader: this.leader });
}
else if (msg.type == VOTE && msg.term == this.term)
{
this.voted++;
this.votes[msg.leader] = this.votes[msg.leader] || [];
this.votes[msg.leader].push(from);
const n = this.votes[msg.leader].length;
if (n == 1 + (0 | this.nodes.length/2))
{
if (msg.leader == this.nodeId)
{
this.leader = msg.leader;
this.state = LEADER;
this._nextTerm(this.leadershipTimeout > 0 ? this.leadershipTimeout : -1);
this.followers = this.votes[this.nodeId];
for (const follower of this.followers)
{
if (follower != this.nodeId)
{
// Send a heartbeat to confirm leadership
this.send(follower, { type: PING, term: this.term });
}
}
this.emit('change', { state: this.state, term: this.term, leader: this.nodeId, followers: this.votes[this.nodeId] });
}
else
{
this._nextTerm(0);
}
}
else if (n > this.nodes.length/2 && this.state == LEADER && msg.leader == this.nodeId)
{
this.state = LEADER;
this._nextTerm(this.leadershipTimeout > 0 ? this.leadershipTimeout : -1);
this.followers = this.votes[this.nodeId];
// Send a heartbeat to confirm leadership
this.send(from, { type: PING, term: this.term });
for (const follower of this.followers)
{
if (follower != this.nodeId)
{
// Send a heartbeat to confirm leadership
this.send(follower, { type: PING, term: this.term });
}
}
this.emit('change', { state: this.state, term: this.term, leader: this.nodeId, followers: this.votes[this.nodeId] });
}
else if (this._isVotingFailed())
else
{
this._nextTerm(0);
}
}
else if (msg.type == PING)
else if (n > this.nodes.length/2 && this.state == LEADER && msg.leader == this.nodeId)
{
if (this.state == CANDIDATE && this.term == msg.term && from == this.leader)
{
this.state = FOLLOWER;
this.emit('change', { state: this.state, term: this.term, leader: this.nodeId });
}
if (this.state == FOLLOWER && from == this.leader)
{
this.markAlive();
}
if (this.leadershipTimeout > 0)
{
this.send(from, { type: PONG, term: this.term, leader: this.leader });
}
this.followers = this.votes[this.nodeId];
// Send a heartbeat to confirm leadership
this.send(from, { type: PING, term: this.term });
this.emit('change', { state: this.state, term: this.term, leader: this.nodeId, followers: this.votes[this.nodeId] });
}
else if (msg.type == PONG && this.state == LEADER)
else if (this._isVotingFailed())
{
if (msg.leader != this.nodeId)
{
this.start();
}
else
{
this._nextTerm(this.leadershipTimeout > 0 ? this.leadershipTimeout : -1);
}
this._nextTerm(0);
}
}
onReceivePing(from, msg)
{
if (this.state == CANDIDATE && this.term == msg.term && from == this.leader)
{
this.state = FOLLOWER;
this.emit('change', { state: this.state, term: this.term, leader: this.nodeId });
}
if (this.state == FOLLOWER && from == this.leader)
{
this.markAlive();
}
if (this.leadershipTimeout > 0)
{
this.send(from, { type: PONG, term: this.term, leader: this.leader });
}
}
onReceivePong(from, msg)
{
if (this.state != LEADER)
{
return;
}
if (msg.leader != this.nodeId)
{
this.start();
}
else
{
this._nextTerm(this.leadershipTimeout > 0 ? this.leadershipTimeout : -1);
}
}