예제 #1
0
func VarFromData(data []byte, exe *dispatcher.Executor, db *db.Databases, vm *VarManager) (*Var, error) {
	seg, _, err := capn.ReadFromMemoryZeroCopy(data)
	if err != nil {
		return nil, err
	}
	varCap := msgs.ReadRootVar(seg)

	v := newVar(common.MakeVarUUId(varCap.Id()), exe, db, vm)
	positions := varCap.Positions()
	if positions.Len() != 0 {
		v.positions = (*common.Positions)(&positions)
	}

	writeTxnId := common.MakeTxnId(varCap.WriteTxnId())
	writeTxnClock := VectorClockFromCap(varCap.WriteTxnClock())
	writesClock := VectorClockFromCap(varCap.WritesClock())
	server.Log(v.UUId, "Restored", writeTxnId)

	if result, err := db.ReadonlyTransaction(func(rtxn *mdbs.RTxn) interface{} {
		return db.ReadTxnBytesFromDisk(rtxn, writeTxnId)
	}).ResultError(); err == nil && result != nil {
		bites := result.([]byte)
		if seg, _, err := capn.ReadFromMemoryZeroCopy(bites); err == nil {
			txn := msgs.ReadRootTxn(seg)
			actions := txn.Actions()
			v.curFrame = NewFrame(nil, v, writeTxnId, &actions, writeTxnClock, writesClock)
			v.curFrameOnDisk = v.curFrame
			v.varCap = &varCap
			return v, nil
		} else {
			return nil, err
		}
	} else {
		return nil, err
	}
}
예제 #2
0
func (lc *locationChecker) locationCheck(cell *varWrapperCell) error {
	vUUId := cell.vUUId
	varCap := cell.varCap
	foundIn := cell.store
	fmt.Printf("%v %v\n", foundIn, vUUId)
	txnId := common.MakeTxnId(varCap.WriteTxnId())

	res, err := foundIn.db.ReadonlyTransaction(func(rtxn *mdbs.RTxn) interface{} {
		return foundIn.db.ReadTxnBytesFromDisk(rtxn, txnId)
	}).ResultError()
	if err != nil {
		return err
	}
	txnBites, ok := res.([]byte)
	if res == nil || (ok && txnBites == nil) {
		return fmt.Errorf("Failed to find %v from %v in %v", txnId, vUUId, foundIn)
	}
	seg, _, err := capn.ReadFromMemoryZeroCopy(txnBites)
	if err != nil {
		return err
	}
	txnCap := msgs.ReadRootTxn(seg)

	positions := varCap.Positions().ToArray()
	rmIds, err := lc.resolver.ResolveHashCodes(positions)
	if err != nil {
		return err
	}
	foundLocal := false
	for _, rmId := range rmIds {
		if foundLocal = rmId == foundIn.rmId; foundLocal {
			break
		}
	}
	if !foundLocal {
		// It must have emigrated but we don't delete.
		txnId = nil
	}
	for _, rmId := range rmIds {
		if rmId == foundIn.rmId {
			continue
		} else if remote, found := lc.stores[rmId]; found {
			res, err := remote.db.ReadonlyTransaction(func(rtxn *mdbs.RTxn) interface{} {
				bites, err := rtxn.Get(remote.db.Vars, vUUId[:])
				if err == mdb.NotFound {
					return nil
				} else if err == nil {
					return bites
				} else {
					return nil
				}
			}).ResultError()
			if err != nil {
				return err
			}
			varBites, ok := res.([]byte)
			if res == nil || (ok && varBites == nil) {
				if vUUId.BootCount() == 1 && vUUId.ConnectionCount() == 0 &&
					(txnId == nil ||
						(txnId.BootCount() == 1 && txnId.ConnectionCount() == 0 &&
							txnCap.Actions().Len() == 1 && txnCap.Actions().At(0).Which() == msgs.ACTION_CREATE)) {
					fmt.Printf("Failed to find %v in %v (%v, %v, %v) but it looks like it's a bad root.\n", vUUId, remote, rmIds, positions, foundIn)
				} else {
					return fmt.Errorf("Failed to find %v in %v (%v, %v, %v)", vUUId, remote, rmIds, positions, foundIn)
				}
			} else {
				seg, _, err := capn.ReadFromMemoryZeroCopy(varBites)
				if err != nil {
					return err
				}
				remoteTxnId := common.MakeTxnId(msgs.ReadRootVar(seg).WriteTxnId())
				if txnId == nil {
					txnId = remoteTxnId
				}
				if remoteTxnId.Compare(txnId) != common.EQ {
					return fmt.Errorf("%v on %v is at %v; on %v is at %v", vUUId, foundIn, txnId, remote, remoteTxnId)
				}
			}
		}
	}
	return nil
}
예제 #3
0
func (s *store) LoadTopology() error {
	res, err := s.db.ReadonlyTransaction(func(rtxn *mdbs.RTxn) interface{} {
		bites, err := rtxn.Get(s.db.Vars, configuration.TopologyVarUUId[:])
		if err != nil {
			rtxn.Error(err)
			return nil
		}
		seg, _, err := capn.ReadFromMemoryZeroCopy(bites)
		if err != nil {
			rtxn.Error(err)
			return nil
		}
		varCap := msgs.ReadRootVar(seg)
		txnId := common.MakeTxnId(varCap.WriteTxnId())
		bites = s.db.ReadTxnBytesFromDisk(rtxn, txnId)
		if bites == nil {
			rtxn.Error(fmt.Errorf("Unable to find txn for topology: %v", txnId))
			return nil
		}
		seg, _, err = capn.ReadFromMemoryZeroCopy(bites)
		if err != nil {
			rtxn.Error(err)
			return nil
		}
		txnCap := msgs.ReadRootTxn(seg)
		actions := txnCap.Actions()
		if actions.Len() != 1 {
			rtxn.Error(fmt.Errorf("Topology txn has %v actions; expected 1", actions.Len()))
			return nil
		}
		action := actions.At(0)
		var refs msgs.VarIdPos_List
		switch action.Which() {
		case msgs.ACTION_WRITE:
			w := action.Write()
			bites = w.Value()
			refs = w.References()
		case msgs.ACTION_READWRITE:
			rw := action.Readwrite()
			bites = rw.Value()
			refs = rw.References()
		case msgs.ACTION_CREATE:
			c := action.Create()
			bites = c.Value()
			refs = c.References()
		default:
			rtxn.Error(fmt.Errorf("Expected topology txn action to be w, rw, or c; found %v", action.Which()))
			return nil
		}

		if refs.Len() != 1 {
			rtxn.Error(fmt.Errorf("Topology txn action has %v references; expected 1", refs.Len()))
			return nil
		}
		rootRef := refs.At(0)

		seg, _, err = capn.ReadFromMemoryZeroCopy(bites)
		if err != nil {
			rtxn.Error(err)
			return nil
		}
		topology, err := configuration.TopologyFromCap(txnId, &rootRef, bites)
		if err != nil {
			rtxn.Error(err)
			return nil
		}
		return topology
	}).ResultError()
	if err != nil {
		return err
	}
	s.topology = res.(*configuration.Topology)
	return nil
}