Пример #1
0
func (this *Paxos) doSaveConfiguration(config *thispb.Configuration) {
	config.MajoritySize = proto.Int32(this.majoritySize)
	config.ProposerList = append([]string{}, this.proposerList...)
	config.AcceptorList = append([]string{}, this.acceptorList...)
	config.LearnerList = append([]string{}, this.learnerList...)
	if this.IsProposer() {
		config.IsProposer = proto.Bool(true)
		config.ProposerIndex = proto.Int32(int32(this.proposerIndex))
	}
	if this.IsAcceptor() {
		config.IsAcceptor = proto.Bool(true)
	}
	if this.IsLearner() {
		config.IsLearner = proto.Bool(true)
	}
}
Пример #2
0
// Configure initializes the paxos agent configuration. Since classic paxos
// doesn't support reconfiguration, this operation can be performed only
// once. Also, local object can be used as a client if it doesn't take any
// role.
//
// proposerList: List of proposer messenger names.
//
// acceptorList: List of acceptor messenger names.
//
// learnerList: List of learner messenger names.
//
// Returns nil on success.
func (this *Paxos) Configure(proposerList, acceptorList,
	learnerList []string) error {

	lock, errLock := this.ctlr.LockAll()
	if errLock != nil {
		return errLock
	}
	defer lock.Unlock()

	if this.majoritySize > 0 {
		this.Errorf("paxos instance is already configured")
		return errs.ErrExist
	}

	// TODO: Check for duplicates.

	learners := make([]string, len(learnerList))
	copy(learners, learnerList)
	sort.Sort(sort.StringSlice(learners))

	acceptors := make([]string, len(acceptorList))
	copy(acceptors, acceptorList)
	sort.Sort(sort.StringSlice(acceptors))
	majoritySize := len(acceptors)/2 + 1

	proposers := make([]string, len(proposerList))
	copy(proposers, proposerList)
	sort.Sort(sort.StringSlice(proposers))

	self := this.msn.UID()

	isLearner := false
	for _, learner := range learners {
		if learner == self {
			isLearner = true
			break
		}
	}

	isAcceptor := false
	for _, acceptor := range acceptors {
		if acceptor == self {
			isAcceptor = true
			break
		}
	}

	isProposer := false
	proposerIndex := -1
	for ii, proposer := range proposers {
		if proposer == self {
			isProposer = true
			proposerIndex = ii
			break
		}
	}

	// Save configuration in the wal.
	config := thispb.Configuration{}
	config.LearnerList = learners
	config.ProposerList = proposers
	config.AcceptorList = acceptors
	config.MajoritySize = proto.Int32(int32(majoritySize))
	if isLearner {
		config.IsLearner = proto.Bool(true)
	}
	if isAcceptor {
		config.IsAcceptor = proto.Bool(true)
	}
	if isProposer {
		config.IsProposer = proto.Bool(true)
		config.ProposerIndex = proto.Int32(int32(proposerIndex))
	}
	return this.doUpdateConfig(&config)
}
Пример #3
0
func (this *Paxos) doRestoreConfig(config *thispb.Configuration) {
	this.learnerList = config.GetLearnerList()
	this.proposerList = config.GetProposerList()
	this.acceptorList = config.GetAcceptorList()

	if config.IsLearner != nil && config.GetIsLearner() {
		atomic.StoreInt32(&this.isLearner, 1)
	}
	if config.IsAcceptor != nil && config.GetIsAcceptor() {
		atomic.StoreInt32(&this.isAcceptor, 1)
	}
	if config.IsProposer != nil && config.GetIsProposer() {
		atomic.StoreInt32(&this.isProposer, 1)
		this.proposerIndex = int(config.GetProposerIndex())
	}
	if config.MajoritySize != nil {
		atomic.StoreInt32(&this.majoritySize, config.GetMajoritySize())
	}
}