示例#1
0
func (lp *libpaxos) ReceivePrepare(args *paxosrpc.ReceivePrepareArgs, reply *paxosrpc.ReceivePrepareReply) error {
	if lp.interruptFunc != nil {
		lp.interruptFunc(lp.myNode.ID, Prepare, lp.slotBox.nextUnknownSlotNumber)
	}

	lp.dataMutex.Lock()

	lp.slotBoxMutex.Lock()
	slot := lp.slotBox.Get(args.CommandSlotNumber)
	lp.slotBoxMutex.Unlock()
	if slot != nil {
		// The Proposer will suggest a slot number for its proposal. If that slot
		// number has already been decided upon, tell the Proposer, and give it
		// the decided value, so it can update its own slot box and choose a
		// different slot number.
		reply.Status = paxosrpc.DecidedValueExists
		reply.DecidedSlotNumber = slot.Number
		reply.DecidedValue = *slot.Value
	} else if lp.highestProposalNumberSeen != nil && args.ProposalNumber.LessThan(lp.highestProposalNumberSeen) {
		// If the proposal number is not highest, reject automatically.
		reply.Status = paxosrpc.Reject
	} else {
		// If the proposal number is highest, then OK it, but also send back
		// any accepted proposals.
		lp.highestProposalNumberSeen = &args.ProposalNumber
		reply.Status = paxosrpc.OK
		if lp.highestAcceptedProposal != nil {
			reply.HasAcceptedProposal = true
			reply.AcceptedProposal = *lp.highestAcceptedProposal
		} else {
			reply.HasAcceptedProposal = false
		}
	}
	lp.dataMutex.Unlock()
	return nil
}