Skip to content

Commit

Permalink
Merge pull request #114 from fengjingchao/dev
Browse files Browse the repository at this point in the history
refine(instance): comments and naming
  • Loading branch information
hongchaodeng committed Jun 2, 2014
2 parents 45e585e + 0b46207 commit 10f83ba
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
33 changes: 25 additions & 8 deletions replica/instance.go
@@ -1,6 +1,8 @@
package replica

// This file implements instance module.
//
// We are listing here the assumptions made in our implementaion.
// @assumption:
// - When a replica pass in the message to instance methods, we assume that the
// internal fields of message is readable only and safe to reference to, except deps.
Expand All @@ -22,9 +24,6 @@ package replica
// - The initial ballot is (epoch, 0, replicaId)
// @decision (04/18/14):
// - Delete rejections to avoid complexity
// @fix:
// send pre-accept for no-op, let it depend on every one before to maintain
// the completeness of dependency graph

import (
"fmt"
Expand Down Expand Up @@ -899,6 +898,26 @@ func (i *Instance) loadRecoveryInfo() {
}
}

// This function is the end of recovery phase and the instance have
// enough knowledge to broadcast messages to peers of his decision.
//
// One important aspect in EPaxos recovery phase is that it needs to
// take care of what's left on previous fast path made by default leader.
// Here are the details not covered in the paper:
//
// If the instance had received at least F identical preaccepted replies
// from non-leader replicas, we couldn't tell whether the default leader had chosen
// fast path or not. At this point, the instance should go to PAXOS-ACCEPT phase.
// And it is guaranteed safety:
// 1. if default leader hadn't gone to fast path, because (1) the instance had
// prepared a quorum of peers, the final commit message wouldn't take outdated,
// previous ones; and (2) including the default leader, there is
// majority who knows the command, this guarantee that any conflict that happen
// afterwards would know it. Therefore, this guarantees both consistency and
// correctness of conflicting.
// 2. if the default leader had gone to fast path, then it must have sent
// commit message of the same commands and dependencies as of the accept message
// this instance sent for recovery. And this is also proven safe.
func (i *Instance) makeRecoveryDecision() (action uint8, msg message.Message) {
i.loadRecoveryInfo()
action = broadcastAction
Expand All @@ -913,16 +932,14 @@ func (i *Instance) makeRecoveryDecision() (action uint8, msg message.Message) {
i.enterAcceptedAsSender()
msg = i.makeAccept()
case preAccepted:
// if former leader committed on fast-path,
// then we must send accept instead of pre-accept
if ir.identicalCount >= i.replica.quorum() {
// If we have F identical replies from non-default-leader preaccepted
// replias, we must send ACCEPT message.
if ir.identicalCount >= i.replica.F() {
i.enterAcceptedAsSender()
msg = i.makeAccept()

} else {
i.enterPreAcceptedAsSender()
msg = i.makePreAccept()
// TODO: action here?
}
case nilStatus:
// get ready to send pre-accept for No-op
Expand Down
4 changes: 4 additions & 0 deletions replica/replica.go
Expand Up @@ -516,6 +516,10 @@ func (r *Replica) quorum() int {
return int(r.Size / 2)
}

func (r *Replica) F() int {
return int(r.Size / 2)
}

func (r *Replica) makeInitialBallot() *message.Ballot {
return message.NewBallot(r.Epoch, 0, r.Id)
}
Expand Down

0 comments on commit 10f83ba

Please sign in to comment.