// 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 }