Split long if-elseif into functions
parent
1d8dfc861c
commit
c96a762ffc
158
tinyraft.js
158
tinyraft.js
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue