-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfollower.js
60 lines (51 loc) · 1.49 KB
/
follower.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
var inherits = require('util').inherits
var EventEmitter = require('events').EventEmitter
var P = require('p-promise')
function Follower(log) {
this.name = 'follower'
this.log = log
this.leaderId = 0
this.beginElection = beginElection.bind(this)
this.electionTimeout = 200
this.electionTimer = null
this.checkVoteResult = checkVoteResult.bind(this)
}
inherits(Follower, EventEmitter)
// Followers don't send RPC calls so results don't matter
Follower.prototype.countVote = function () {}
Follower.prototype.entriesAppended = function () {}
function beginElection() {
this.emit('changeRole', 'candidate')
}
Follower.prototype.resetElectionTimeout = function () {
clearTimeout(this.electionTimer)
this.electionTimer = setTimeout(
this.beginElection,
this.electionTimeout + Math.random() * this.electionTimeout
)
}
Follower.prototype.assertRole = function (info) {
if (info.term > this.log.currentTerm) {
this.log.currentTerm = info.term
this.log.votedFor = 0
}
}
Follower.prototype.requestVote = function (vote) {
return this.log.requestVote(vote)
.then(this.checkVoteResult)
}
function checkVoteResult(voteGranted) {
if (voteGranted) {
this.resetElectionTimeout()
}
return voteGranted
}
Follower.prototype.appendEntries = function (info) {
this.leaderId = info.leaderId
this.resetElectionTimeout()
return this.log.appendEntries(info)
}
Follower.prototype.request = function (entry) {
return P.reject({ message: 'not the leader', leaderId: this.leaderId })
}
module.exports = Follower