Exemplo n.º 1
0
func NewVar(uuid *common.VarUUId, exe *dispatcher.Executor, disk *mdbs.MDBServer, vm *VarManager) *Var {
	v := newVar(uuid, exe, disk, vm)

	clock := NewVectorClock().Bump(*v.UUId, 0)
	written := NewVectorClock().Bump(*v.UUId, 0)
	v.curFrame = NewFrame(nil, v, nil, nil, clock, written)

	seg := capn.NewBuffer(nil)
	varCap := msgs.NewRootVar(seg)
	varCap.SetId(v.UUId[:])
	v.varCap = &varCap

	return v
}
Exemplo n.º 2
0
func (v *Var) maybeWriteFrame(f *frame, action *localAction, positions *common.Positions) {
	if v.writeInProgress != nil {
		v.writeInProgress = func() {
			v.writeInProgress = nil
			v.maybeWriteFrame(f, action, positions)
		}
		return
	}
	v.writeInProgress = func() {
		v.writeInProgress = nil
		v.maybeMakeInactive()
	}

	oldVarCap := *v.varCap

	varSeg := capn.NewBuffer(nil)
	varCap := msgs.NewRootVar(varSeg)
	v.varCap = &varCap
	varCap.SetId(oldVarCap.Id())

	if positions != nil {
		varCap.SetPositions(capn.UInt8List(*positions))
	} else {
		varCap.SetPositions(oldVarCap.Positions())
	}

	varCap.SetWriteTxnId(f.frameTxnId[:])
	varCap.SetWriteTxnClock(f.frameTxnClock.AddToSeg(varSeg))
	varCap.SetWritesClock(f.frameWritesClock.AddToSeg(varSeg))
	varData := server.SegToBytes(varSeg)

	txnBytes := action.TxnRootBytes()

	// to ensure correct order of writes, schedule the write from
	// the current go-routine...
	future := v.disk.ReadWriteTransaction(false, func(rwtxn *mdbs.RWTxn) (interface{}, error) {
		if err := db.WriteTxnToDisk(rwtxn, f.frameTxnId, txnBytes); err != nil {
			return nil, err
		}
		if err := rwtxn.Put(db.DB.Vars, v.UUId[:], varData, 0); err != nil {
			return nil, err
		}
		if v.curFrameOnDisk != nil {
			return nil, db.DeleteTxnFromDisk(rwtxn, v.curFrameOnDisk.frameTxnId)
		}
		return nil, nil
	})
	go func() {
		// ... but process the result in a new go-routine to avoid blocking the executor.
		if _, err := future.ResultError(); err != nil {
			log.Println("Var error when writing to disk:", err)
			return
		}
		// Switch back to the right go-routine
		v.applyToVar(func() {
			server.Log(v.UUId, "Wrote", f.frameTxnId)
			v.curFrameOnDisk = f
			for ancestor := f.parent; ancestor != nil && ancestor.DescendentOnDisk(); ancestor = ancestor.parent {
			}
			v.writeInProgress()
		})
	}()
}