func (txn *Txn) submitRetryTransaction() error { reads := make(map[common.VarUUId]*objectState) for ancestor := txn; ancestor != nil; ancestor = ancestor.parent { for _, obj := range ancestor.objs { if _, found := reads[*obj.Id]; !found && obj.state.txn == ancestor && obj.state.read { reads[*obj.Id] = obj.state } } } seg := capn.NewBuffer(nil) cTxn := msgs.NewClientTxn(seg) cTxn.SetRetry(true) actions := msgs.NewClientActionList(seg, len(reads)) cTxn.SetActions(actions) idx := 0 for _, state := range reads { action := actions.At(idx) action.SetVarId(state.Id[:]) action.SetRead() action.Read().SetVersion(state.curVersion[:]) idx++ } outcome, _, err := txn.conn.submitTransaction(&cTxn) if err != nil { return err } txn.stats.TxnId = common.MakeTxnId(outcome.FinalId()) for ancestor := txn; ancestor != nil; ancestor = ancestor.parent { ancestor.resetInProgress = true } return nil }
func (fo *frameOpen) createRollClientTxn() (*msgs.ClientTxn, map[common.VarUUId]*common.Positions) { var origWrite *msgs.Action vUUIdBytes := fo.v.UUId[:] for idx, l := 0, fo.frameTxnActions.Len(); idx < l; idx++ { action := fo.frameTxnActions.At(idx) if bytes.Equal(action.VarId(), vUUIdBytes) { origWrite = &action break } } seg := capn.NewBuffer(nil) ctxn := msgs.NewClientTxn(seg) ctxn.SetRetry(false) actions := msgs.NewClientActionList(seg, 1) ctxn.SetActions(actions) action := actions.At(0) action.SetVarId(fo.v.UUId[:]) action.SetRoll() roll := action.Roll() roll.SetVersion(fo.frameTxnId[:]) var refs msgs.VarIdPos_List switch origWrite.Which() { case msgs.ACTION_WRITE: ow := origWrite.Write() roll.SetValue(ow.Value()) refs = ow.References() case msgs.ACTION_READWRITE: owr := origWrite.Readwrite() roll.SetValue(owr.Value()) refs = owr.References() case msgs.ACTION_CREATE: oc := origWrite.Create() roll.SetValue(oc.Value()) refs = oc.References() case msgs.ACTION_ROLL: owr := origWrite.Roll() roll.SetValue(owr.Value()) refs = owr.References() default: panic(fmt.Sprintf("%v unexpected action type when building roll: %v", fo.frame, origWrite.Which())) } posMap := make(map[common.VarUUId]*common.Positions) posMap[*fo.v.UUId] = fo.v.positions refVarList := seg.NewDataList(refs.Len()) roll.SetReferences(refVarList) for idx, l := 0, refs.Len(); idx < l; idx++ { ref := refs.At(idx) vUUId := common.MakeVarUUId(ref.Id()) pos := common.Positions(ref.Positions()) posMap[*vUUId] = &pos refVarList.Set(idx, vUUId[:]) } return &ctxn, posMap }
func loadVar(vUUId *common.VarUUId, conn *Connection) ([]*common.VarUUId, time.Duration, error) { start := time.Now() seg := capn.NewBuffer(nil) cTxn := msgs.NewClientTxn(seg) actions := msgs.NewClientActionList(seg, 1) cTxn.SetActions(actions) action := actions.At(0) action.SetVarId(vUUId[:]) action.SetRead() read := action.Read() read.SetVersion(common.VersionZero[:]) _, modifiedVars, err := conn.submitTransaction(&cTxn) return modifiedVars, time.Now().Sub(start), err }
func (txn *Txn) submitToServer() (bool, error) { // log.Println(txn, "Submitting to conn") reads := make([]*objectState, 0, len(txn.objs)) writes := make([]*objectState, 0, len(txn.objs)) readwrites := make([]*objectState, 0, len(txn.objs)) creates := make([]*objectState, 0, len(txn.objs)) for _, obj := range txn.objs { state := obj.state switch { case state.create: creates = append(creates, state) case state.read && state.write: readwrites = append(readwrites, state) case state.write: writes = append(writes, state) case state.read: reads = append(reads, state) } } totalLen := len(reads) + len(writes) + len(readwrites) + len(creates) if totalLen == 0 { return false, nil } // log.Printf("%v r:%v; w:%v; rw:%v; c%v; ", txn, len(reads), len(writes), len(readwrites), len(creates)) total := make([]*objectState, totalLen) copy(total, reads) writeThresh := len(reads) copy(total[writeThresh:], writes) readwriteThresh := writeThresh + len(writes) copy(total[readwriteThresh:], readwrites) createThresh := readwriteThresh + len(readwrites) copy(total[createThresh:], creates) seg := capn.NewBuffer(nil) cTxn := msgs.NewClientTxn(seg) cTxn.SetRetry(false) actions := msgs.NewClientActionList(seg, totalLen) cTxn.SetActions(actions) idx := 0 for _, state := range total { action := actions.At(idx) action.SetVarId(state.Id[:]) if idx < writeThresh { action.SetRead() action.Read().SetVersion(state.curVersion[:]) } else { refs := seg.NewDataList(len(state.curObjectRefs)) for idy, ref := range state.curObjectRefs { refs.Set(idy, ref.Id[:]) } switch { case idx < readwriteThresh: action.SetWrite() write := action.Write() write.SetValue(state.curValue) write.SetReferences(refs) case idx < createThresh: action.SetReadwrite() rw := action.Readwrite() rw.SetVersion(state.curVersion[:]) rw.SetValue(state.curValue) rw.SetReferences(refs) default: action.SetCreate() create := action.Create() create.SetValue(state.curValue) create.SetReferences(refs) } } idx++ } outcome, _, err := txn.conn.submitTransaction(&cTxn) if err != nil { return false, err } txn.stats.TxnId = common.MakeTxnId(outcome.FinalId()) return outcome.Which() == msgs.CLIENTTXNOUTCOME_ABORT, nil }