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, } }
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) } } }
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], } } } } }
// 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) } }