示例#1
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],
				}
			}
		}
	}
}
示例#2
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)
	}
}