Esempio n. 1
0
// StartMonitorFeed starts a goroutine which processes events published to the
// supplied Subscription. The goroutine will continue running until the
// Subscription's Events feed is closed.
func (nsm *NodeStatusMonitor) StartMonitorFeed(feed *util.Feed) {
	sub := feed.Subscribe()
	go func() {
		for event := range sub.Events() {
			if syncEvent, ok := event.(*TestSyncEvent); ok {
				syncEvent.consume()
			}

			ProcessNodeEvent(nsm, event)
			storage.ProcessStoreEvent(nsm, event)
		}
	}()
}
Esempio n. 2
0
func TestNodeStatusMonitor(t *testing.T) {
	defer leaktest.AfterTest(t)
	desc1 := &proto.RangeDescriptor{
		RaftID:   1,
		StartKey: proto.Key("a"),
		EndKey:   proto.Key("b"),
	}
	desc2 := &proto.RangeDescriptor{
		RaftID:   2,
		StartKey: proto.Key("b"),
		EndKey:   proto.Key("c"),
	}
	stats := engine.MVCCStats{
		LiveBytes:       1,
		KeyBytes:        2,
		ValBytes:        2,
		IntentBytes:     1,
		LiveCount:       1,
		KeyCount:        1,
		ValCount:        1,
		IntentCount:     1,
		IntentAge:       1,
		GCBytesAge:      1,
		LastUpdateNanos: 1 * 1E9,
	}

	monitorStopper := stop.NewStopper()
	storeStopper := stop.NewStopper()
	feed := &util.Feed{}
	monitor := NewNodeStatusMonitor()
	sub := feed.Subscribe()
	monitorStopper.RunWorker(func() {
		for event := range sub.Events() {
			storage.ProcessStoreEvent(monitor, event)
			ProcessNodeEvent(monitor, event)
		}
	})

	for i := 0; i < 3; i++ {
		id := proto.StoreID(i + 1)
		eventList := []interface{}{
			&storage.StartStoreEvent{
				StoreID: id,
			},
			&storage.BeginScanRangesEvent{ // Begin scan phase.
				StoreID: id,
			},
			&storage.UpdateRangeEvent{ // Update during scan, expect it to be ignored.
				StoreID: id,
				Desc:    desc1,
				Stats:   stats,
				Delta:   stats,
			},
			&storage.RegisterRangeEvent{
				StoreID: id,
				Desc:    desc2,
				Stats:   stats,
				Scan:    false, // should lead to this being ignored
			},
			&storage.RegisterRangeEvent{
				StoreID: id,
				Desc:    desc1,
				Stats:   stats,
				Scan:    true, // not ignored
			},
			&storage.UpdateRangeEvent{ // Update during scan after register, should be picked up
				StoreID: id,
				Desc:    desc1,
				Stats:   stats,
				Delta:   stats,
			},
			&storage.EndScanRangesEvent{ // End Scan.
				StoreID: id,
			},
			&storage.RegisterRangeEvent{
				StoreID: id,
				Desc:    desc2,
				Stats:   stats,
				Scan:    true, // ignored, not in ScanRanges mode
			},
			&storage.UpdateRangeEvent{
				StoreID: id,
				Desc:    desc1,
				Stats:   stats,
				Delta:   stats,
			},
			&storage.UpdateRangeEvent{
				StoreID: id,
				Desc:    desc1,
				Stats:   stats,
				Delta:   stats,
			},
			&storage.SplitRangeEvent{
				StoreID: id,
				Original: storage.UpdateRangeEvent{
					StoreID: id,
					Desc:    desc1,
					Stats:   stats,
					Delta:   stats,
				},
				New: storage.RegisterRangeEvent{
					StoreID: id,
					Desc:    desc2,
					Stats:   stats,
					Scan:    false,
				},
			},
			&storage.UpdateRangeEvent{
				StoreID: id,
				Desc:    desc2,
				Stats:   stats,
				Delta:   stats,
			},
			&storage.UpdateRangeEvent{
				StoreID: id,
				Desc:    desc2,
				Stats:   stats,
				Delta:   stats,
			},
			&CallSuccessEvent{
				NodeID: proto.NodeID(1),
				Method: proto.Get,
			},
			&CallSuccessEvent{
				NodeID: proto.NodeID(1),
				Method: proto.Put,
			},
			&CallErrorEvent{
				NodeID: proto.NodeID(1),
				Method: proto.Scan,
			},
		}
		storeStopper.RunWorker(func() {
			for _, event := range eventList {
				feed.Publish(event)
			}
		})
	}

	storeStopper.Stop()
	feed.Close()
	monitorStopper.Stop()

	expectedStats := engine.MVCCStats{
		LiveBytes:       6,
		KeyBytes:        12,
		ValBytes:        12,
		IntentBytes:     6,
		LiveCount:       6,
		KeyCount:        6,
		ValCount:        6,
		IntentCount:     6,
		IntentAge:       6,
		GCBytesAge:      6,
		LastUpdateNanos: 1 * 1E9,
	}

	if a, e := len(monitor.stores), 3; a != e {
		t.Fatalf("unexpected number of stores recorded by monitor; expected %d, got %d", e, a)
	}
	for id, store := range monitor.stores {
		if a, e := store.stats, expectedStats; !reflect.DeepEqual(a, e) {
			t.Errorf("monitored stats for store %d did not match expectation: %v != %v", id, a, e)
		}
		if a, e := store.rangeCount, int64(2); a != e {
			t.Errorf("monitored range count for store %d did not match expectation: %d != %d", id, a, e)
		}
	}

	if a, e := monitor.callCount, int64(6); a != e {
		t.Errorf("monitored stats for node recorded wrong number of ops %d, expected %d", a, e)
	}
	if a, e := monitor.callErrors, int64(3); a != e {
		t.Errorf("monitored stats for node recorded wrong number of errors %d, expected %d", a, e)
	}
}
Esempio n. 3
0
// StartMonitorFeed starts a goroutine which processes events published to the
// supplied Subscription. The goroutine will continue running until the
// Subscription's Events feed is closed.
func (nsm *NodeStatusMonitor) StartMonitorFeed(feed *util.Feed) {
	feed.Subscribe(func(event interface{}) {
		ProcessNodeEvent(nsm, event)
		storage.ProcessStoreEvent(nsm, event)
	})
}