示例#1
0
func newTwoBTxnVotesSender(outcome *msgs.Outcome, txnId *common.TxnId, submitter common.RMId, recipients ...common.RMId) *twoBTxnVotesSender {
	submitterSeg := capn.NewBuffer(nil)
	submitterMsg := msgs.NewRootMessage(submitterSeg)
	submitterMsg.SetSubmissionOutcome(*outcome)

	if outcome.Which() == msgs.OUTCOME_ABORT {
		abort := outcome.Abort()
		abort.SetResubmit() // nuke out the updates as proposers don't need them.
	}

	seg := capn.NewBuffer(nil)
	msg := msgs.NewRootMessage(seg)
	twoB := msgs.NewTwoBTxnVotes(seg)
	msg.SetTwoBTxnVotes(twoB)
	twoB.SetOutcome(*outcome)

	server.Log(txnId, "Sending 2B to", recipients)

	return &twoBTxnVotesSender{
		msg:          server.SegToBytes(seg),
		recipients:   recipients,
		submitterMsg: server.SegToBytes(submitterSeg),
		submitter:    submitter,
	}
}
示例#2
0
func (cts *ClientTxnSubmitter) addCreatesToCache(outcome *msgs.Outcome) {
	actions := outcome.Txn().Actions()
	for idx, l := 0, actions.Len(); idx < l; idx++ {
		action := actions.At(idx)
		if action.Which() == msgs.ACTION_CREATE {
			varUUId := common.MakeVarUUId(action.VarId())
			positions := common.Positions(action.Create().Positions())
			cts.hashCache.AddPosition(varUUId, &positions)
		}
	}
}
示例#3
0
func (vc versionCache) UpdateFromCommit(txnId *common.TxnId, outcome *msgs.Outcome) {
	clock := eng.VectorClockFromCap(outcome.Commit())
	actions := outcome.Txn().Actions()
	for idx, l := 0, actions.Len(); idx < l; idx++ {
		action := actions.At(idx)
		if action.Which() != msgs.ACTION_READ {
			vUUId := common.MakeVarUUId(action.VarId())
			if c, found := vc[*vUUId]; found {
				c.txnId = txnId
				c.clockElem = clock.Clock[*vUUId]
			} else {
				vc[*vUUId] = &cached{
					txnId:     txnId,
					clockElem: clock.Clock[*vUUId],
				}
			}
		}
	}
}
示例#4
0
// Callback (from network/paxos)
func (tro *txnReceiveOutcome) BallotOutcomeReceived(outcome *msgs.Outcome) {
	if tro.outcomeClock != nil || tro.aborted {
		// We've already been here. Be silent if we receive extra outcomes.
		return
	}
	if tro.Retry && tro.currentState == &tro.txnAwaitLocalBallots {
		tro.nextState()
	}
	if tro.currentState != tro {
		// We've received the outcome too early! Be noisy!
		panic(fmt.Sprintf("%v error: Ballot outcome received with txn in wrong state: %v\n", tro.Id, tro.currentState))
		return
	}
	switch outcome.Which() {
	case msgs.OUTCOME_COMMIT:
		tro.outcomeClock = VectorClockFromCap(outcome.Commit())
	default:
		tro.aborted = true
	}
	tro.nextState() // advance state FIRST!
	if tro.preAbortedBool {
		if !tro.aborted {
			panic(fmt.Sprintf("%v We preAborted the txn, but the txn outcome is to commit!", tro.Id))
		}
		return
	}
	for idx := 0; idx < len(tro.localActions); idx++ {
		action := &tro.localActions[idx]
		f := func(v *Var, err error) {
			if err != nil {
				panic(fmt.Sprintf("%v error (%v, aborted? %v, preAborted? %v, frame == nil? %v): %v", tro.Id, tro, tro.aborted, tro.preAbortedBool, action.frame == nil, err))
			} else {
				v.ReceiveTxnOutcome(action)
			}
		}
		// Should only have to create missing vars if we're a learner (i.e. !voter).
		tro.vd.ApplyToVar(f, !tro.voter, action.vUUId)
	}
}