Skip to content

Commit

Permalink
refactored proposer a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
dannycoates committed Dec 31, 2012
1 parent 7e65e5f commit aa38d9e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 23 deletions.
29 changes: 15 additions & 14 deletions proposer/propose-state.js
@@ -1,44 +1,46 @@
module.exports = function (assert, inherits, EventEmitter, Prepare, Proposal) {

function Paxos(proposer, instance, ballot) {
function ProposeState(proposer, instance, ballot) {
EventEmitter.call(this)
this.proposerId = proposer.id
this.instance = instance
this.ballot = ballot || 0
this.value = null
this.valueBallot = 0

this.timer = null
// TODO: decide where timeouts go. At this point there's arguments for
// here, where they become part of the state, or in the communication
// layer which keeps the state "time free". I think I'd prefer to keep
// knowledge of time out of the state, but it seems easier to implement
// here. So lets try to do it "there" and only come back if its too ugly.

this.promises = []
this.majority = proposer.majority
}
inherits(Paxos, EventEmitter)
inherits(ProposeState, EventEmitter)

Paxos.create = function (proposer, instance, ballot) {
var state = new Paxos(proposer, instance, ballot)
ProposeState.create = function (proposer, instance, ballot) {
var state = new ProposeState(proposer, instance, ballot)
state.on('prepare', proposer.onPrepare)
state.on('accept', proposer.onAccept)
state.on('propose', proposer.onPropose)
return state
}

Paxos.prototype.nextBallot = function (previous) {
ProposeState.prototype.nextBallot = function (previous) {
var id = previous % 100
var counter = (previous - id) + 100 //here's the increment
this.ballot = counter + this.proposerId
this.promises = []
return this.ballot
}

Paxos.prototype.prepare = function (previousBallot) {
clearTimeout(this.timer)
ProposeState.prototype.prepare = function (previousBallot) {
this.nextBallot(previousBallot || this.ballot)
this.emit('prepare', new Prepare(this.instance, this.ballot))
}

Paxos.prototype.proposal = function () {
clearTimeout(this.timer)
ProposeState.prototype.proposal = function () {
var proposal = new Proposal(this.instance, this.ballot, this.value, this.valueBallot)
var event = this.value ? 'accept' : 'propose'
this.emit(event, proposal)
Expand All @@ -52,7 +54,7 @@ module.exports = function (assert, inherits, EventEmitter, Prepare, Proposal) {
return (a.valueBallot || 0) > (b.valueBallot || 0) ? a : b
}

Paxos.prototype.promised = function (proposal) {
ProposeState.prototype.promised = function (proposal) {
assert.equal(this.instance, proposal.instance)

if (this.ballot < proposal.ballot) {
Expand All @@ -74,12 +76,11 @@ module.exports = function (assert, inherits, EventEmitter, Prepare, Proposal) {
}
}

Paxos.prototype.complete = function (proposer) {
clearTimeout(this.timer)
ProposeState.prototype.complete = function (proposer) {
this.removeListener('prepare', proposer.onPrepare)
this.removeListener('accept', proposer.onAccept)
this.removeListener('propose', proposer.onPropose)
}

return Paxos
return ProposeState
}
19 changes: 10 additions & 9 deletions proposer/proposer.js
@@ -1,4 +1,4 @@
module.exports = function (assert, inherits, EventEmitter, Paxos) {
module.exports = function (assert, inherits, EventEmitter, ProposeState) {

function Proposer(id, majority, learner) {
assert(id < 100, "max id is 99")
Expand All @@ -15,18 +15,19 @@ module.exports = function (assert, inherits, EventEmitter, Paxos) {
}
inherits(Proposer, EventEmitter)

Proposer.prototype.prepare = function (instanceId) {
instanceId = instanceId || this.instanceCounter++
var instance = this.instances[instanceId] || Paxos.create(this, instanceId)
Proposer.prototype.instance = function (instanceId, ballot) {
var instance = this.instances[instanceId] ||
ProposeState.create(this, instanceId, ballot)
this.instances[instanceId] = instance
instance.prepare()
return instance
}

Proposer.prototype.prepare = function (instanceId) {
this.instance(instanceId || this.instanceCounter++).prepare()
}

Proposer.prototype.promised = function (proposal) {
var instance = this.instances[proposal.instance] ||
Paxos.create(this, proposal.instance, proposal.ballot)
this.instances[proposal.instance] = instance
instance.promised(proposal)
this.instance(proposal.instance, proposal.ballot).promised(proposal)
}

Proposer.prototype.accept = function (proposal) {
Expand Down

0 comments on commit aa38d9e

Please sign in to comment.