-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcandidate.js
71 lines (59 loc) · 1.71 KB
/
candidate.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
61
62
63
64
65
66
67
68
69
70
71
var inherits = require('util').inherits
var EventEmitter = require('events').EventEmitter
var P = require('p-promise')
function Candidate(log) {
this.name = 'candidate'
this.log = log
this.votes = {}
this.votes['self'] = true
this.beginElection = beginElection.bind(this)
this.electionTimeout = 200
this.electionTimer = null
}
inherits(Candidate, EventEmitter)
function beginElection() {
this.emit('changeRole', 'candidate')
}
Candidate.prototype.clearElectionTimeout = function () {
clearTimeout(this.electionTimer)
}
Candidate.prototype.resetElectionTimeout = function () {
this.clearElectionTimeout()
this.electionTimer = setTimeout(
this.beginElection,
this.electionTimeout + Math.random() * this.electionTimeout
)
}
Candidate.prototype.assertRole = function (info, rpc) { //TODO rpc is ugly
var currentTerm = this.log.currentTerm
if (info.term > currentTerm) {
this.log.currentTerm = info.term
this.log.votedFor = 0
this.clearElectionTimeout()
this.emit('changeRole', 'follower')
}
else if (info.term === currentTerm && rpc === 'appendEntries') {
this.clearElectionTimeout()
this.emit('changeRole', 'follower')
}
}
Candidate.prototype.countVote = function (vote, totalPeers) {
if (vote.voteGranted) {
this.votes[vote.id] = true
if (Object.keys(this.votes).length > (totalPeers + 1) / 2) {
this.clearElectionTimeout()
this.emit('changeRole', 'leader')
}
}
}
Candidate.prototype.entriesAppended = function () {} // noop
Candidate.prototype.requestVote = function (vote) {
return P(false)
}
Candidate.prototype.appendEntries = function (info) {
return P(false)
}
Candidate.prototype.request = function (entry) {
return P.reject({ message: 'no leader' })
}
module.exports = Candidate