Esempio n. 1
0
File: paxos.go Progetto: bvk/ascent
// LearnRPC handles ClassicPaxos.Learn rpc.
func (this *Paxos) LearnRPC(header *msgpb.Header,
	request *thispb.LearnRequest) (status error) {

	if !this.IsLearner() {
		this.Errorf("this paxos instance is not a learner; rejecting %s", header)
		return errs.ErrInvalid
	}

	lock, errLock := this.ctlr.TimedLock(msg.RequestTimeout(header), "learner")
	if errLock != nil {
		return errLock
	}
	defer lock.Unlock()

	acceptor := header.GetMessengerId()
	if this.chosenValue == nil {
		change := thispb.LearnerChange{}
		change.VotedBallotList = request.VotedBallotList
		change.VotedValueList = request.VotedValueList
		change.VotedAcceptor = proto.String(acceptor)
		if err := this.doUpdateLearner(&change); err != nil {
			this.Errorf("could not update learner state: %v", err)
			return err
		}
	}

	response := thispb.LearnResponse{}
	if this.chosenValue != nil {
		response.KnowsChosenValue = proto.Bool(true)
	}
	message := thispb.PaxosMessage{}
	message.LearnResponse = &response
	errSend := msg.SendResponseProto(this.msn, header, &message)
	if errSend != nil {
		this.Errorf("could not respond to learn request from %s: %v", acceptor,
			errSend)
		return errSend
	}
	return nil
}