Beispiel #1
0
// Ranges returns range info for the server specified
func (s *statusServer) Ranges(ctx context.Context, req *serverpb.RangesRequest) (*serverpb.RangesResponse, error) {
	nodeID, local, err := s.parseNodeID(req.NodeId)
	if err != nil {
		return nil, grpc.Errorf(codes.InvalidArgument, err.Error())
	}

	if !local {
		status, err := s.dialNode(nodeID)
		if err != nil {
			return nil, err
		}
		return status.Ranges(ctx, req)
	}

	output := serverpb.RangesResponse{
		Ranges: make([]serverpb.RangeInfo, 0, s.stores.GetStoreCount()),
	}
	err = s.stores.VisitStores(func(store *storage.Store) error {
		// Use IterateRangeDescriptors to read from the engine only
		// because it's already exported.
		err := storage.IterateRangeDescriptors(store.Engine(),
			func(desc roachpb.RangeDescriptor) (bool, error) {
				rep, err := store.GetReplica(desc.RangeID)
				if err != nil {
					return true, err
				}
				status := rep.RaftStatus()
				var raftState string
				if status != nil {
					// We can't put the whole raft.Status object in the json output
					// because it contains a map with integer keys. Just extract
					// the most interesting bit for now.
					raftState = status.RaftState.String()
				} else {
					raftState = "StateDormant"
				}
				state := rep.State()
				output.Ranges = append(output.Ranges, serverpb.RangeInfo{
					Span: serverpb.PrettySpan{
						StartKey: desc.StartKey.String(),
						EndKey:   desc.EndKey.String(),
					},
					RaftState: raftState,
					State:     state,
				})
				return false, nil
			})
		return err
	})
	if err != nil {
		return nil, grpc.Errorf(codes.Internal, err.Error())
	}
	return &output, nil
}
Beispiel #2
0
// Ranges returns range info for the server specified
func (s *statusServer) Ranges(ctx context.Context, req *serverpb.RangesRequest) (*serverpb.RangesResponse, error) {
	nodeID, local, err := s.parseNodeID(req.NodeId)
	if err != nil {
		return nil, grpc.Errorf(codes.InvalidArgument, err.Error())
	}

	if !local {
		status, err := s.dialNode(nodeID)
		if err != nil {
			return nil, err
		}
		return status.Ranges(ctx, req)
	}

	output := serverpb.RangesResponse{
		Ranges: make([]serverpb.RangeInfo, 0, s.stores.GetStoreCount()),
	}

	convertRaftStatus := func(raftStatus *raft.Status) serverpb.RaftState {
		var state serverpb.RaftState
		if raftStatus == nil {
			state.State = "StateDormant"
			return state
		}

		state.ReplicaID = raftStatus.ID
		state.HardState = raftStatus.HardState
		state.Applied = raftStatus.Applied

		// Grab Lead and State, which together form the SoftState.
		state.Lead = raftStatus.Lead
		state.State = raftStatus.RaftState.String()

		state.Progress = make(map[uint64]serverpb.RaftState_Progress)
		for id, progress := range raftStatus.Progress {
			state.Progress[id] = serverpb.RaftState_Progress{
				Match:           progress.Match,
				Next:            progress.Next,
				Paused:          progress.Paused,
				PendingSnapshot: progress.PendingSnapshot,
				State:           progress.State.String(),
			}
		}

		return state
	}

	err = s.stores.VisitStores(func(store *storage.Store) error {
		// Use IterateRangeDescriptors to read from the engine only
		// because it's already exported.
		err := storage.IterateRangeDescriptors(ctx, store.Engine(),
			func(desc roachpb.RangeDescriptor) (bool, error) {
				rep, err := store.GetReplica(desc.RangeID)
				if err != nil {
					return true, err
				}
				output.Ranges = append(output.Ranges, serverpb.RangeInfo{
					Span: serverpb.PrettySpan{
						StartKey: desc.StartKey.String(),
						EndKey:   desc.EndKey.String(),
					},
					RaftState: convertRaftStatus(rep.RaftStatus()),
					State:     rep.State(),
				})
				return false, nil
			})
		return err
	})
	if err != nil {
		return nil, grpc.Errorf(codes.Internal, err.Error())
	}
	return &output, nil
}