-
Notifications
You must be signed in to change notification settings - Fork 11
/
recorder.js
64 lines (54 loc) · 2.47 KB
/
recorder.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
const assert = require('assert')
const Monotonic = require('./monotonic')
// TODO Remember that the code is more complicated than the messaging. Let the
// messages absorb some of the complexity of the code. (Divide them. Restrict
// their structure.)
class Recorder {
constructor (paxos) {
this.register = {
body: {
promise: paxos.top.promise,
body: paxos.top.body,
previous: paxos.top.previous
},
previous: null
}
this._paxos = paxos
}
// We do not need to handle accept messages.
// If we received an accept message it would mean that a proposer had a promise
// from this islander but the Acceptor that issued the promise has been replaced
// by this recorder. That in turn means that we have received a new, stable
// government and that government has been written to the atomic log. Our atomic
// log is therefore ahead of the atomic log of the sender of the accept message
// so the request would have been rejected because the logs are out of sync.
// The previous promise of the registered entry submitted will match the
// registered entry recorder.
// This one is because our previous entry is always synonymous with what is in
// our atomic log. If we receive a message with a different previous entry then
// the atomic logs are out of sync and our whole algorithm has failed. If it is
// merely the case that we're getting a register message that was delayed or
// lost a race to write a recover fiat government, then the request would be
// rejected because the logs are out of sync.
//
request (now, request) {
assert(/^prepare|register$/.test(request.method), 'unexpected message to record')
// Anything else is going to get caught synchronization and rejected.
switch (request.method) {
case 'prepare':
return this._paxos._prepare(now, request)
case 'register':
assert(request.register.body.previous == this.register.body.promise, 'register has unexpected previous')
assert(this._paxos.top.promise == this.register.body.promise, 'recorder and log out of sync')
this.register = request.register
return { method: 'receive', promise: '0/0' }
}
}
createRecorder () {
return new Recorder(this._paxos)
}
inspect () {
return { type: 'Recorder' }
}
}
module.exports = Recorder