예제 #1
0
파일: app.go 프로젝트: jyzhe/beehive
// RuntimeMap generates an automatic runtime map function based on the given
// rcv function.
//
// If there was an error in the rcv function, it will return "nil" and the
// message will be dropped.
func RuntimeMap(rcv RcvFunc) MapFunc {
	return func(msg Msg, ctx MapContext) (cells MappedCells) {
		defer func() {
			if r := recover(); r != nil {
				glog.Errorf("runtime map cannot find the mapped cells")
				cells = nil
			}
		}()

		q := ctx.(*qee)
		rCtx := runtimeRcvContext{
			qee:   q,
			state: state.NewTransactional(q.app.newState()),
		}

		if err := rcv(msg, rCtx); err != nil {
			return nil
		}

		for _, d := range rCtx.state.Dicts() {
			d.ForEach(func(k string, v interface{}) bool {
				cells = append(cells, CellKey{Dict: d.Name(), Key: k})
				return true
			})
		}

		return
	}
}
예제 #2
0
파일: app.go 프로젝트: jyzhe/beehive
func (a *app) initQee() {
	a.qee = &qee{
		dataCh:       newMsgChannel(a.hive.config.DataChBufSize),
		ctrlCh:       make(chan cmdAndChannel, a.hive.config.CmdChBufSize),
		placementCh:  make(chan placementRes, a.hive.config.CmdChBufSize),
		hive:         a.hive,
		app:          a,
		bees:         make(map[uint64]*bee),
		state:        state.NewTransactional(a.newState()),
		pendingCells: make(map[CellKey]*pendingCells),
	}
}
예제 #3
0
파일: bee.go 프로젝트: jyzhe/beehive
func (b *bee) handleMsgLeader(mhs []msgAndHandler) {

	usetx := b.app.transactional()
	if usetx && len(mhs) > 1 {
		b.stateL2 = state.NewTransactional(b.stateL1)
		b.stateL1.BeginTx()
	}

	for i := range mhs {
		if usetx {
			b.BeginTx()
		}

		mh := mhs[i]
		if glog.V(2) {
			glog.Infof("%v handles message %v", b, mh.msg)
		}
		b.callRcv(mh)

		if usetx {
			var err error
			if b.stateL2 == nil {
				err = b.CommitTx()
			} else if len(b.msgBufL1) == 0 && b.stateL2.HasEmptyTx() {
				// If there is no pending L1 message and there is no state change,
				// emit the buffered messages in L2 as a shortcut.
				b.throttle(b.msgBufL2)
				b.resetTx(b.stateL2, &b.msgBufL2)
			} else {
				err = b.commitTxL2()
			}

			if err != nil && err != state.ErrNoTx {
				glog.Errorf("%v cannot commit a transaction: %v", b, err)
			}
		}
	}

	if !usetx || b.stateL2 == nil {
		return
	}

	b.stateL2 = nil
	if err := b.CommitTx(); err != nil && err != state.ErrNoTx {
		glog.Errorf("%v cannot commit a transaction: %v", b, err)
	}
}
예제 #4
0
파일: bee.go 프로젝트: jyzhe/beehive
func (b *bee) setState(s state.State) {
	b.stateL1 = state.NewTransactional(s)
}
예제 #5
0
파일: bee_test.go 프로젝트: jyzhe/beehive
func BenchmarkBeePersistence(b *testing.B) {
	b.StopTimer()
	log.SetOutput(ioutil.Discard)
	hive := &hive{
		id: 1,
		config: HiveConfig{
			StatePath:      "/tmp/bhtest_bench_bee",
			RaftTick:       100 * time.Millisecond,
			RaftHBTicks:    1,
			RaftElectTicks: 5,
			RaftInFlights:  1,
			RaftFsyncTick:  1 * time.Second,
		},
		collector: &noOpStatCollector{},
	}
	removeState(hive.config.StatePath)
	hive.ticker = randtime.NewTicker(hive.config.RaftTick, 0)
	hive.registry = newRegistry(hive.String())
	ncfg := raft.Config{
		ID:     hive.id,
		Name:   hive.String(),
		Send:   hive.sendRaft,
		Ticker: hive.ticker.C,
	}
	hive.node = raft.StartMultiNode(ncfg)

	bee := bee{
		beeID: 1,
		beeColony: Colony{
			ID:     1,
			Leader: 1,
		},
		hive: hive,
		app: &app{
			name:  "test",
			flags: appFlagTransactional | appFlagPersistent,
		},
		stateL1:   state.NewTransactional(state.NewInMem()),
		dataCh:    newMsgChannel(uint(b.N)),
		batchSize: 1024,
	}
	bee.becomeLeader()
	hive.registry.addBee(BeeInfo{
		ID:     1,
		Hive:   1,
		App:    "test",
		Colony: bee.colony(),
	})
	if err := bee.createGroup(); err != nil {
		b.Fatal(err)
	}

	b.StartTimer()

	h := benchBeeHandler{data: []byte{1, 1, 1, 1}}
	mhs := make([]msgAndHandler, bee.batchSize)
	for j := uint(0); j < bee.batchSize; j++ {
		mhs[j] = msgAndHandler{
			msg:     &msg{},
			handler: h,
		}
	}
	for i := uint(0); i < uint(b.N); i += bee.batchSize {
		bee.handleMsg(mhs)
	}

	b.StopTimer()
	time.Sleep(1 * time.Second)
	hive.node.Stop()
}
예제 #6
0
func newMockContext() *mockContext {
	ctx := &mockContext{
		Transactional: state.NewTransactional(state.NewInMem()),
	}
	return ctx
}