From 9e78d69773f62332469d91237f80518458751bc2 Mon Sep 17 00:00:00 2001 From: disksing Date: Tue, 14 May 2019 16:32:38 +0800 Subject: [PATCH 1/8] client, server: support ScanRegions gRPC protocol Signed-off-by: disksing --- client/client.go | 25 +++++++++++++++++++++++++ go.mod | 2 ++ go.sum | 4 ++++ server/grpc_service.go | 19 +++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/client/client.go b/client/client.go index dcc6466cc72..a5cba7f3b6d 100644 --- a/client/client.go +++ b/client/client.go @@ -52,6 +52,9 @@ type Client interface { GetPrevRegion(ctx context.Context, key []byte) (*metapb.Region, *metapb.Peer, error) // GetRegionByID gets a region and its leader Peer from PD by id. GetRegionByID(ctx context.Context, regionID uint64) (*metapb.Region, *metapb.Peer, error) + // ScanRegion gets a list of regions, starts from the region that contains key. + // Limit limits the maximum number of regions returned. + ScanRegions(ctx context.Context, key []byte, limit int) ([]*metapb.Region, []*metapb.Peer, error) // GetStore gets a store from PD by store id. // The store may expire later. Caller is responsible for caching and taking care // of store change. @@ -681,6 +684,28 @@ func (c *client) GetRegionByID(ctx context.Context, regionID uint64) (*metapb.Re return resp.GetRegion(), resp.GetLeader(), nil } +func (c *client) ScanRegions(ctx context.Context, key []byte, limit int) ([]*metapb.Region, []*metapb.Peer, error) { + if span := opentracing.SpanFromContext(ctx); span != nil { + span := opentracing.StartSpan("pdclient.ScanRegions", opentracing.ChildOf(span.Context())) + defer span.Finish() + } + start := time.Now() + defer cmdDuration.WithLabelValues("scan_regions").Observe(time.Since(start).Seconds()) + ctx, cancel := context.WithTimeout(ctx, pdTimeout) + resp, err := c.leaderClient().ScanRegions(ctx, &pdpb.ScanRegionsRequest{ + Header: c.requestHeader(), + RegionKey: key, + Limit: int32(limit), + }) + cancel() + if err != nil { + cmdFailedDuration.WithLabelValues("scan_regions").Observe(time.Since(start).Seconds()) + c.ScheduleCheckLeader() + return nil, nil, errors.WithStack(err) + } + return resp.GetRegions(), resp.GetLeaders(), nil +} + func (c *client) GetStore(ctx context.Context, storeID uint64) (*metapb.Store, error) { if span := opentracing.SpanFromContext(ctx); span != nil { span = opentracing.StartSpan("pdclient.GetStore", opentracing.ChildOf(span.Context())) diff --git a/go.mod b/go.mod index 55930166716..9dd70a381e4 100644 --- a/go.mod +++ b/go.mod @@ -48,3 +48,5 @@ require ( gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) + +replace github.com/pingcap/kvproto => github.com/disksing/kvproto v0.0.0-20190514082446-71cc78e0e15f diff --git a/go.sum b/go.sum index 37ac9eb6bdf..b196059b3fe 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/disksing/kvproto v0.0.0-20190514080946-95d18116297d h1:xDtiIJV55wNp2gWaaTLVPfP3cJSV/cl9rCkjgPZ2EQo= +github.com/disksing/kvproto v0.0.0-20190514080946-95d18116297d/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= +github.com/disksing/kvproto v0.0.0-20190514082446-71cc78e0e15f h1:4Qa5Ws0Gfrxdpx7zqGZvH+DOq1uHnQLjVzT8j4VyZLo= +github.com/disksing/kvproto v0.0.0-20190514082446-71cc78e0e15f/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e h1:Fw7ZmgiklsLh5EQWyHh1sumKSCG1+yjEctIpGKib87s= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= diff --git a/server/grpc_service.go b/server/grpc_service.go index ba78d697e2f..31f4dd3c889 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -447,6 +447,25 @@ func (s *Server) GetRegionByID(ctx context.Context, request *pdpb.GetRegionByIDR }, nil } +// ScanRegions implements gRPC PDServer. +func (s *Server) ScanRegions(ctx context.Context, request *pdpb.ScanRegionsRequest) (*pdpb.ScanRegionsResponse, error) { + if err := s.validateRequest(request.GetHeader()); err != nil { + return nil, err + } + + cluster := s.GetRaftCluster() + if cluster == nil { + return &pdpb.ScanRegionsResponse{Header: s.notBootstrappedHeader()}, nil + } + regions := cluster.ScanRegionsByKey(request.GetRegionKey(), int(request.GetLimit())) + resp := &pdpb.ScanRegionsResponse{Header: s.header()} + for _, r := range regions { + resp.Regions = append(resp.Regions, r.GetMeta()) + resp.Leaders = append(resp.Leaders, r.GetLeader()) + } + return resp, nil +} + // AskSplit implements gRPC PDServer. func (s *Server) AskSplit(ctx context.Context, request *pdpb.AskSplitRequest) (*pdpb.AskSplitResponse, error) { if err := s.validateRequest(request.GetHeader()); err != nil { From 46241929401583773141898d5212d852d0d904a7 Mon Sep 17 00:00:00 2001 From: disksing Date: Tue, 14 May 2019 16:48:38 +0800 Subject: [PATCH 2/8] add test Signed-off-by: disksing --- client/client_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/client/client_test.go b/client/client_test.go index 03fa97b036b..7c3be59fb36 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -260,6 +260,53 @@ func (s *testClientSuite) TestGetPrevRegion(c *C) { c.Succeed() } +func (s *testClientSuite) TestScanRegions(c *C) { + regionLen := 10 + regions := make([]*metapb.Region, 0, regionLen) + for i := 0; i < regionLen; i++ { + regionID := regionIDAllocator.alloc() + r := &metapb.Region{ + Id: regionID, + RegionEpoch: &metapb.RegionEpoch{ + ConfVer: 1, + Version: 1, + }, + StartKey: []byte{byte(i)}, + EndKey: []byte{byte(i + 1)}, + Peers: peers, + } + regions = append(regions, r) + req := &pdpb.RegionHeartbeatRequest{ + Header: newHeader(s.srv), + Region: r, + Leader: peers[0], + } + err := s.regionHeartbeat.Send(req) + c.Assert(err, IsNil) + } + + // Wait for region heartbeats. + testutil.WaitUntil(c, func(c *C) bool { + regions, _, err := s.client.ScanRegions(context.Background(), []byte{0}, 10) + return err == nil && len(regions) == 10 + }) + + check := func(start []byte, limit int, expect []*metapb.Region) { + regions, leaders, err := s.client.ScanRegions(context.Background(), start, limit) + c.Assert(err, IsNil) + c.Assert(regions, HasLen, len(expect)) + c.Assert(leaders, HasLen, len(expect)) + for i := range expect { + c.Assert(regions[i], DeepEquals, expect[i]) + c.Assert(leaders[i], DeepEquals, expect[i].Peers[0]) + } + } + + check([]byte{0}, 10, regions) + check([]byte{1}, 5, regions[1:6]) + check([]byte{100}, 1, nil) +} + func (s *testClientSuite) TestGetRegionByID(c *C) { regionID := regionIDAllocator.alloc() region := &metapb.Region{ From 4a81a5df57218f95ed334541240f4a7c945929bb Mon Sep 17 00:00:00 2001 From: disksing Date: Tue, 14 May 2019 19:34:47 +0800 Subject: [PATCH 3/8] update kvproto Signed-off-by: disksing --- client/client.go | 2 +- client/client_test.go | 10 +++++----- go.mod | 2 +- go.sum | 8 ++------ server/grpc_service.go | 2 +- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/client/client.go b/client/client.go index a5cba7f3b6d..dc25b0d4c51 100644 --- a/client/client.go +++ b/client/client.go @@ -686,7 +686,7 @@ func (c *client) GetRegionByID(ctx context.Context, regionID uint64) (*metapb.Re func (c *client) ScanRegions(ctx context.Context, key []byte, limit int) ([]*metapb.Region, []*metapb.Peer, error) { if span := opentracing.SpanFromContext(ctx); span != nil { - span := opentracing.StartSpan("pdclient.ScanRegions", opentracing.ChildOf(span.Context())) + span = opentracing.StartSpan("pdclient.ScanRegions", opentracing.ChildOf(span.Context())) defer span.Finish() } start := time.Now() diff --git a/client/client_test.go b/client/client_test.go index 7c3be59fb36..589b9c277e8 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -287,17 +287,17 @@ func (s *testClientSuite) TestScanRegions(c *C) { // Wait for region heartbeats. testutil.WaitUntil(c, func(c *C) bool { - regions, _, err := s.client.ScanRegions(context.Background(), []byte{0}, 10) - return err == nil && len(regions) == 10 + scanRegions, _, err := s.client.ScanRegions(context.Background(), []byte{0}, 10) + return err == nil && len(scanRegions) == 10 }) check := func(start []byte, limit int, expect []*metapb.Region) { - regions, leaders, err := s.client.ScanRegions(context.Background(), start, limit) + scanRegions, leaders, err := s.client.ScanRegions(context.Background(), start, limit) c.Assert(err, IsNil) - c.Assert(regions, HasLen, len(expect)) + c.Assert(scanRegions, HasLen, len(expect)) c.Assert(leaders, HasLen, len(expect)) for i := range expect { - c.Assert(regions[i], DeepEquals, expect[i]) + c.Assert(scanRegions[i], DeepEquals, expect[i]) c.Assert(leaders[i], DeepEquals, expect[i].Peers[0]) } } diff --git a/go.mod b/go.mod index 9dd70a381e4..319b2b8f3f4 100644 --- a/go.mod +++ b/go.mod @@ -49,4 +49,4 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) -replace github.com/pingcap/kvproto => github.com/disksing/kvproto v0.0.0-20190514082446-71cc78e0e15f +replace github.com/pingcap/kvproto => github.com/disksing/kvproto v0.0.0-20190514082446-10fed9e3e749 diff --git a/go.sum b/go.sum index b196059b3fe..1719f944abd 100644 --- a/go.sum +++ b/go.sum @@ -20,10 +20,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/disksing/kvproto v0.0.0-20190514080946-95d18116297d h1:xDtiIJV55wNp2gWaaTLVPfP3cJSV/cl9rCkjgPZ2EQo= -github.com/disksing/kvproto v0.0.0-20190514080946-95d18116297d/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= -github.com/disksing/kvproto v0.0.0-20190514082446-71cc78e0e15f h1:4Qa5Ws0Gfrxdpx7zqGZvH+DOq1uHnQLjVzT8j4VyZLo= -github.com/disksing/kvproto v0.0.0-20190514082446-71cc78e0e15f/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= +github.com/disksing/kvproto v0.0.0-20190514082446-10fed9e3e749 h1:4L5GbVHu7dnr7VUMrKBxgm2BA2OwX4vm8gEJE3k85Dc= +github.com/disksing/kvproto v0.0.0-20190514082446-10fed9e3e749/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e h1:Fw7ZmgiklsLh5EQWyHh1sumKSCG1+yjEctIpGKib87s= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -103,8 +101,6 @@ github.com/pingcap/errors v0.10.1 h1:fGVuPMtwNcxbzQ3aoRyyi6kxvXKMkEsceP81f3b8wsk github.com/pingcap/errors v0.10.1/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pingcap/gofail v0.0.0-20181217135706-6a951c1e42c3 h1:04yuCf5NMvLU8rB2m4Qs3rynH7EYpMno3lHkewIOdMo= github.com/pingcap/gofail v0.0.0-20181217135706-6a951c1e42c3/go.mod h1:DazNTg0PTldtpsQiT9I5tVJwV1onHMKBBgXzmJUlMns= -github.com/pingcap/kvproto v0.0.0-20190327032727-3d8cb3a30d5d h1:LJYJl+cBhkkTWD79n+n9Bp4agQ85SdF9YKY4zEtL9Kw= -github.com/pingcap/kvproto v0.0.0-20190327032727-3d8cb3a30d5d/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7 h1:kOHAMalwF69bJrtWrOdVaCSvZjLucrJhP4NQKIu6uM4= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/server/grpc_service.go b/server/grpc_service.go index 31f4dd3c889..0fdd491175a 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -457,7 +457,7 @@ func (s *Server) ScanRegions(ctx context.Context, request *pdpb.ScanRegionsReque if cluster == nil { return &pdpb.ScanRegionsResponse{Header: s.notBootstrappedHeader()}, nil } - regions := cluster.ScanRegionsByKey(request.GetRegionKey(), int(request.GetLimit())) + regions := cluster.ScanRegionsByKey(request.GetStartKey(), int(request.GetLimit())) resp := &pdpb.ScanRegionsResponse{Header: s.header()} for _, r := range regions { resp.Regions = append(resp.Regions, r.GetMeta()) From d2ff892ddf25e184185d2c9e0fd5a88176df7992 Mon Sep 17 00:00:00 2001 From: disksing Date: Tue, 14 May 2019 19:37:46 +0800 Subject: [PATCH 4/8] fix compile error Signed-off-by: disksing --- client/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/client.go b/client/client.go index dc25b0d4c51..d95451c3961 100644 --- a/client/client.go +++ b/client/client.go @@ -693,9 +693,9 @@ func (c *client) ScanRegions(ctx context.Context, key []byte, limit int) ([]*met defer cmdDuration.WithLabelValues("scan_regions").Observe(time.Since(start).Seconds()) ctx, cancel := context.WithTimeout(ctx, pdTimeout) resp, err := c.leaderClient().ScanRegions(ctx, &pdpb.ScanRegionsRequest{ - Header: c.requestHeader(), - RegionKey: key, - Limit: int32(limit), + Header: c.requestHeader(), + StartKey: key, + Limit: int32(limit), }) cancel() if err != nil { From 8e7a2b39dc3c245071d7ab022d87b20e3014d411 Mon Sep 17 00:00:00 2001 From: disksing Date: Thu, 16 May 2019 11:21:25 +0800 Subject: [PATCH 5/8] update kvproto Signed-off-by: disksing --- go.mod | 4 +--- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index ab4acc1ea48..3d81846c830 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/pingcap/errcode v0.0.0-20180921232412-a1a7271709d9 github.com/pingcap/errors v0.10.1 // indirect github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c - github.com/pingcap/kvproto v0.0.0-20190327032727-3d8cb3a30d5d + github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7 github.com/pkg/errors v0.8.1 github.com/prometheus/client_golang v0.8.0 @@ -48,5 +48,3 @@ require ( gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) - -replace github.com/pingcap/kvproto => github.com/disksing/kvproto v0.0.0-20190514082446-10fed9e3e749 diff --git a/go.sum b/go.sum index 4aa43835475..f5666357e1c 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/disksing/kvproto v0.0.0-20190514082446-10fed9e3e749 h1:4L5GbVHu7dnr7VUMrKBxgm2BA2OwX4vm8gEJE3k85Dc= -github.com/disksing/kvproto v0.0.0-20190514082446-10fed9e3e749/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e h1:Fw7ZmgiklsLh5EQWyHh1sumKSCG1+yjEctIpGKib87s= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -109,6 +107,8 @@ github.com/pingcap/errors v0.10.1 h1:fGVuPMtwNcxbzQ3aoRyyi6kxvXKMkEsceP81f3b8wsk github.com/pingcap/errors v0.10.1/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c h1:hvQd3aOLKLF7xvRV6DzvPkKY4QXzfVbjU1BhW0d9yL8= github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c/go.mod h1:DNS3Qg7bEDhU6EXNHF+XSv/PGznQaMJ5FWvctpm6pQI= +github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c h1:pY/MQQ5UajEHfSnQS8rFAM9gw9bBKzqBl414cdfhpRQ= +github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7 h1:kOHAMalwF69bJrtWrOdVaCSvZjLucrJhP4NQKIu6uM4= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= From 394b06361c45b8ac875b1705fea2838afbbb1304 Mon Sep 17 00:00:00 2001 From: disksing Date: Thu, 16 May 2019 15:14:53 +0800 Subject: [PATCH 6/8] add test and fix when leader is nil Signed-off-by: disksing --- client/client_test.go | 13 ++++++++++++- server/grpc_service.go | 6 +++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/client/client_test.go b/client/client_test.go index 589b9c277e8..2ab45e970dc 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -291,14 +291,25 @@ func (s *testClientSuite) TestScanRegions(c *C) { return err == nil && len(scanRegions) == 10 }) + // Set leader of region3 to nil. + region3 := core.NewRegionInfo(regions[3], nil) + s.srv.GetRaftCluster().HandleRegionHeartbeat(region3) + check := func(start []byte, limit int, expect []*metapb.Region) { scanRegions, leaders, err := s.client.ScanRegions(context.Background(), start, limit) c.Assert(err, IsNil) c.Assert(scanRegions, HasLen, len(expect)) c.Assert(leaders, HasLen, len(expect)) + c.Log("scanRegions", scanRegions) + c.Log("expect", expect) + c.Log("scanLeaders", leaders) for i := range expect { c.Assert(scanRegions[i], DeepEquals, expect[i]) - c.Assert(leaders[i], DeepEquals, expect[i].Peers[0]) + if scanRegions[i].GetId() == region3.GetID() { + c.Assert(leaders[i], DeepEquals, &metapb.Peer{}) + } else { + c.Assert(leaders[i], DeepEquals, expect[i].Peers[0]) + } } } diff --git a/server/grpc_service.go b/server/grpc_service.go index 0fdd491175a..a5b249d4ef9 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -460,8 +460,12 @@ func (s *Server) ScanRegions(ctx context.Context, request *pdpb.ScanRegionsReque regions := cluster.ScanRegionsByKey(request.GetStartKey(), int(request.GetLimit())) resp := &pdpb.ScanRegionsResponse{Header: s.header()} for _, r := range regions { + leader := r.GetLeader() + if leader == nil { + leader = &metapb.Peer{} + } resp.Regions = append(resp.Regions, r.GetMeta()) - resp.Leaders = append(resp.Leaders, r.GetLeader()) + resp.Leaders = append(resp.Leaders, leader) } return resp, nil } From 88ce7eda4317ab84f559f8a1214d09b48739c134 Mon Sep 17 00:00:00 2001 From: disksing Date: Thu, 16 May 2019 20:12:18 +0800 Subject: [PATCH 7/8] improve comment Signed-off-by: disksing --- client/client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/client.go b/client/client.go index d95451c3961..4b8c36b20a8 100644 --- a/client/client.go +++ b/client/client.go @@ -54,6 +54,8 @@ type Client interface { GetRegionByID(ctx context.Context, regionID uint64) (*metapb.Region, *metapb.Peer, error) // ScanRegion gets a list of regions, starts from the region that contains key. // Limit limits the maximum number of regions returned. + // If a region has no leader, corresponding leader will be placed a peer with + // empty value (PeerID is 0). ScanRegions(ctx context.Context, key []byte, limit int) ([]*metapb.Region, []*metapb.Peer, error) // GetStore gets a store from PD by store id. // The store may expire later. Caller is responsible for caching and taking care From 890e6d078a74c4309e2a71696442bcfde51a0258 Mon Sep 17 00:00:00 2001 From: disksing Date: Thu, 16 May 2019 20:14:28 +0800 Subject: [PATCH 8/8] improve comment Signed-off-by: disksing --- client/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/client.go b/client/client.go index 4b8c36b20a8..5e00aea837f 100644 --- a/client/client.go +++ b/client/client.go @@ -54,8 +54,8 @@ type Client interface { GetRegionByID(ctx context.Context, regionID uint64) (*metapb.Region, *metapb.Peer, error) // ScanRegion gets a list of regions, starts from the region that contains key. // Limit limits the maximum number of regions returned. - // If a region has no leader, corresponding leader will be placed a peer with - // empty value (PeerID is 0). + // If a region has no leader, corresponding leader will be placed by a peer + // with empty value (PeerID is 0). ScanRegions(ctx context.Context, key []byte, limit int) ([]*metapb.Region, []*metapb.Peer, error) // GetStore gets a store from PD by store id. // The store may expire later. Caller is responsible for caching and taking care