Example #1
0
// ElectRPC implements the Election.Elect rpc.
func (this *Election) ElectRPC(reqHeader *msgpb.Header,
	request *thispb.ElectRequest) (status error) {

	if !this.InCommittee() {
		return errs.ErrInvalid
	}

	round := request.GetElectionRound()
	current := this.CurrentRound()
	if round != current+1 {
		this.Errorf("could not begin election round %d because current round "+
			"is only at %d", round, current)
		return errs.ErrStale
	}

	uid := this.PaxosUIDFromElectionRound(round)
	paxos, errGet := this.GetPaxosInstance(uid)
	if errGet != nil {
		this.Errorf("could not find paxos instance for uid %s: %v", uid, errGet)
		return errGet
	}

	this.Infof("starting new election for round %d using paxos instance %s",
		round, uid)

	clientID := reqHeader.GetMessengerId()
	proposedValue := []byte(clientID)
	chosenValue, errPropose := paxos.Propose(proposedValue,
		msg.RequestTimeout(reqHeader))
	if errPropose != nil {
		this.Errorf("could not propose %s as the leader for election round %d: %v",
			proposedValue, round, errPropose)
		return errPropose
	}
	winner := string(chosenValue)

	// Send the election result.
	response := thispb.ElectResponse{}
	response.ElectionRound = proto.Int64(round)
	response.ElectionWinner = proto.String(winner)
	message := thispb.ElectionMessage{}
	message.ElectResponse = &response
	if err := msg.SendResponseProto(this.msn, reqHeader, &message); err != nil {
		this.Errorf("could not send election response to %s: %v", clientID, err)
		return err
	}
	return nil
}