diff --git a/client/go.mod b/client/go.mod index e3b9192bb30c..22ef56aa4177 100644 --- a/client/go.mod +++ b/client/go.mod @@ -7,7 +7,7 @@ require ( github.com/pingcap/check v0.0.0-20211026125417-57bd13f7b5f0 github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 - github.com/pingcap/kvproto v0.0.0-20220302110454-c696585a961b + github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748 github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee github.com/prometheus/client_golang v1.11.0 go.uber.org/goleak v1.1.11 diff --git a/client/go.sum b/client/go.sum index c705a06c2475..becfbccfe126 100644 --- a/client/go.sum +++ b/client/go.sum @@ -43,8 +43,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -79,7 +79,7 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -106,8 +106,8 @@ github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c h1:xpW9bvK+HuuTm github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 h1:C3N3itkduZXDZFh4N3vQ5HEtld3S+Y+StULhWVvumU0= github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew= -github.com/pingcap/kvproto v0.0.0-20220302110454-c696585a961b h1:/OL63rEIcCEivpgTLCkhxVbO3RMxSuHtsKWSgDwS6oY= -github.com/pingcap/kvproto v0.0.0-20220302110454-c696585a961b/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748 h1:i4MBe1zGq9/r3BH6rTRunizi4T59fpNk8hvBCrB5UAY= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee h1:VO2t6IBpfvW34TdtD/G10VvnGqjLic1jzOuHjUb5VqM= github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= @@ -150,6 +150,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -185,6 +187,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -196,8 +200,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -208,6 +214,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -220,6 +227,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -232,7 +240,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -243,6 +250,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191107010934-f79515f33823/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index 4f0f2dc3591e..b76938f07069 100644 --- a/go.mod +++ b/go.mod @@ -14,10 +14,11 @@ require ( github.com/docker/go-units v0.4.0 github.com/gin-gonic/gin v1.7.4 github.com/go-echarts/go-echarts v1.0.0 - github.com/gogo/protobuf v1.3.1 + github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.3.4 github.com/google/btree v1.0.0 github.com/gorilla/mux v1.7.4 + github.com/gorilla/websocket v1.4.1 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mattn/go-shellwords v1.0.12 github.com/mgechev/revive v1.0.2 @@ -28,7 +29,7 @@ require ( github.com/pingcap/errcode v0.3.0 github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce - github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a + github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748 github.com/pingcap/log v0.0.0-20210906054005-afc726e70354 github.com/pingcap/sysutil v0.0.0-20211208032423-041a72e5860d github.com/pingcap/tidb-dashboard v0.0.0-20220316134154-e88e27120168 @@ -40,6 +41,7 @@ require ( github.com/swaggo/http-swagger v0.0.0-20200308142732-58ac5e232fba github.com/swaggo/swag v1.6.6-0.20200529100950-7c765ddd0476 github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 + github.com/tidwall/gjson v1.9.3 // indirect github.com/unrolled/render v1.0.1 github.com/urfave/negroni v0.3.0 // Fix panic in unit test with go >= 1.14, ref: etcd-io/bbolt#201 https://github.com/etcd-io/bbolt/pull/201 diff --git a/go.sum b/go.sum index b2820c6aa460..d3c364ed15c2 100644 --- a/go.sum +++ b/go.sum @@ -172,8 +172,9 @@ github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v0.0.0-20180717141946-636bf0302bc9/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -213,8 +214,9 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -291,6 +293,7 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= @@ -397,8 +400,8 @@ github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce h1:Y1kCxlCtlPTMt github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce/go.mod h1:w4PEZ5y16LeofeeGwdgZB4ddv9bLyDuIX+ljstgKZyk= github.com/pingcap/kvproto v0.0.0-20191211054548-3c6b38ea5107/go.mod h1:WWLmULLO7l8IOcQG+t+ItJ3fEcrL5FxF0Wu+HrMy26w= github.com/pingcap/kvproto v0.0.0-20200411081810-b85805c9476c/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= -github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a h1:0ZnJ8JPtPVGG3qF1G9Kz0NYDEj8BraNEJeQlmwUF6BA= -github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748 h1:i4MBe1zGq9/r3BH6rTRunizi4T59fpNk8hvBCrB5UAY= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM= @@ -505,12 +508,15 @@ github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7 github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/thoas/go-funk v0.8.0 h1:JP9tKSvnpFVclYgDM0Is7FD9M4fhPvqA0s0BsXmzSRQ= github.com/thoas/go-funk v0.8.0/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= -github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= -github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= +github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E= +github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= @@ -541,6 +547,7 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= @@ -607,6 +614,7 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -628,6 +636,7 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -637,6 +646,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -707,6 +717,8 @@ golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200225230052-807dcd883420/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= diff --git a/pkg/mock/mockcluster/mockcluster.go b/pkg/mock/mockcluster/mockcluster.go index df3fe92c598e..b54d62a5ea83 100644 --- a/pkg/mock/mockcluster/mockcluster.go +++ b/pkg/mock/mockcluster/mockcluster.go @@ -71,7 +71,7 @@ func NewCluster(ctx context.Context, opts *config.PersistOptions) *Cluster { } // It should be updated to the latest feature version. clus.PersistOptions.SetClusterVersion(versioninfo.MinSupportedVersion(versioninfo.HotScheduleWithQuery)) - clus.RegionLabeler, _ = labeler.NewRegionLabeler(storage.NewStorageWithMemoryBackend()) + clus.RegionLabeler, _ = labeler.NewRegionLabeler(ctx, storage.NewStorageWithMemoryBackend(), time.Second*5) return clus } diff --git a/server/api/region_label_test.go b/server/api/region_label_test.go index 9a19ee97fd72..a2f536291533 100644 --- a/server/api/region_label_test.go +++ b/server/api/region_label_test.go @@ -73,7 +73,8 @@ func (s *testRegionLabelSuite) TestGetSet(c *C) { err = readJSONWithBody(testDialClient, s.urlPrefix+"rules/ids", []byte(`["rule1", "rule3"]`), &resp) c.Assert(err, IsNil) - c.Assert(resp, DeepEquals, []*labeler.LabelRule{rules[0], rules[2]}) + expects := []*labeler.LabelRule{rules[0], rules[2]} + c.Assert(resp, DeepEquals, expects) _, err = doDelete(testDialClient, s.urlPrefix+"rule/"+url.QueryEscape("rule2/a/b")) c.Assert(err, IsNil) diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index c437e8b9aab0..a7923d2bc408 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -56,6 +56,9 @@ import ( // backgroundJobInterval is the interval to run background jobs. var backgroundJobInterval = 10 * time.Second +// regionLabelGCInterval is the interval to run region-label's GC work. +const regionLabelGCInterval = time.Hour + // DefaultMinResolvedTSPersistenceInterval is the default value of min resolved ts persistence interval. var DefaultMinResolvedTSPersistenceInterval = 10 * time.Second @@ -250,7 +253,7 @@ func (c *RaftCluster) Start(s Server) error { } } - c.regionLabeler, err = labeler.NewRegionLabeler(c.storage) + c.regionLabeler, err = labeler.NewRegionLabeler(c.ctx, c.storage, regionLabelGCInterval) if err != nil { return err } diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index 59de3e0c23c7..0c865647cbc4 100644 --- a/server/cluster/cluster_test.go +++ b/server/cluster/cluster_test.go @@ -1197,7 +1197,7 @@ func newTestCluster(ctx context.Context, opt *config.PersistOptions) *testCluste panic(err) } } - rc.regionLabeler, _ = labeler.NewRegionLabeler(storage) + rc.regionLabeler, _ = labeler.NewRegionLabeler(ctx, storage, time.Second*5) return &testCluster{RaftCluster: rc} } diff --git a/server/grpc_service.go b/server/grpc_service.go index 0c45b7c2a660..b0b18d29172e 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -60,6 +60,27 @@ var ( ErrNotStarted = status.Errorf(codes.Unavailable, "server not started") ) +type forwardFn func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) + +func (s *GrpcServer) unaryMiddleware(ctx context.Context, header *pdpb.RequestHeader, fn forwardFn) (rsp interface{}, err error) { + failpoint.Inject("customTimeout", func() { + time.Sleep(5 * time.Second) + }) + forwardedHost := getForwardedHost(ctx) + if !s.isLocalRequest(forwardedHost) { + client, err := s.getDelegateClient(ctx, forwardedHost) + if err != nil { + return nil, err + } + ctx = grpcutil.ResetForwardContext(ctx) + return fn(ctx, client) + } + if err := s.validateRequest(header); err != nil { + return nil, err + } + return nil, nil +} + // GetMembers implements gRPC PDServer. func (s *GrpcServer) GetMembers(context.Context, *pdpb.GetMembersRequest) (*pdpb.GetMembersResponse, error) { // Here we purposely do not check the cluster ID because the client does not know the correct cluster ID @@ -350,18 +371,13 @@ func watchTSDeadline(ctx context.Context, tsDeadlineCh <-chan deadline) { // Bootstrap implements gRPC PDServer. func (s *GrpcServer) Bootstrap(ctx context.Context, request *pdpb.BootstrapRequest) (*pdpb.BootstrapResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).Bootstrap(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.BootstrapResponse), nil } rc := s.GetRaftCluster() @@ -386,18 +402,13 @@ func (s *GrpcServer) Bootstrap(ctx context.Context, request *pdpb.BootstrapReque // IsBootstrapped implements gRPC PDServer. func (s *GrpcServer) IsBootstrapped(ctx context.Context, request *pdpb.IsBootstrappedRequest) (*pdpb.IsBootstrappedResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).IsBootstrapped(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.IsBootstrappedResponse), err } rc := s.GetRaftCluster() @@ -409,18 +420,13 @@ func (s *GrpcServer) IsBootstrapped(ctx context.Context, request *pdpb.IsBootstr // AllocID implements gRPC PDServer. func (s *GrpcServer) AllocID(ctx context.Context, request *pdpb.AllocIDRequest) (*pdpb.AllocIDResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).AllocID(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.AllocIDResponse), err } // We can use an allocator for all types ID allocation. @@ -437,18 +443,13 @@ func (s *GrpcServer) AllocID(ctx context.Context, request *pdpb.AllocIDRequest) // GetStore implements gRPC PDServer. func (s *GrpcServer) GetStore(ctx context.Context, request *pdpb.GetStoreRequest) (*pdpb.GetStoreResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetStore(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetStoreResponse), err } rc := s.GetRaftCluster() @@ -485,18 +486,13 @@ func checkStore(rc *cluster.RaftCluster, storeID uint64) *pdpb.Error { // PutStore implements gRPC PDServer. func (s *GrpcServer) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (*pdpb.PutStoreResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).PutStore(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.PutStoreResponse), err } rc := s.GetRaftCluster() @@ -540,21 +536,13 @@ func (s *GrpcServer) PutStore(ctx context.Context, request *pdpb.PutStoreRequest // GetAllStores implements gRPC PDServer. func (s *GrpcServer) GetAllStores(ctx context.Context, request *pdpb.GetAllStoresRequest) (*pdpb.GetAllStoresResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetAllStores(ctx, request) } - - failpoint.Inject("customTimeout", func() { - time.Sleep(5 * time.Second) - }) - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetAllStoresResponse), err } rc := s.GetRaftCluster() @@ -582,18 +570,13 @@ func (s *GrpcServer) GetAllStores(ctx context.Context, request *pdpb.GetAllStore // StoreHeartbeat implements gRPC PDServer. func (s *GrpcServer) StoreHeartbeat(ctx context.Context, request *pdpb.StoreHeartbeatRequest) (*pdpb.StoreHeartbeatResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).StoreHeartbeat(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.StoreHeartbeatResponse), err } if request.GetStats() == nil { @@ -941,18 +924,13 @@ func (s *GrpcServer) RegionHeartbeat(stream pdpb.PD_RegionHeartbeatServer) error // GetRegion implements gRPC PDServer. func (s *GrpcServer) GetRegion(ctx context.Context, request *pdpb.GetRegionRequest) (*pdpb.GetRegionResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetRegion(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetRegionResponse), nil } rc := s.GetRaftCluster() @@ -974,18 +952,13 @@ func (s *GrpcServer) GetRegion(ctx context.Context, request *pdpb.GetRegionReque // GetPrevRegion implements gRPC PDServer func (s *GrpcServer) GetPrevRegion(ctx context.Context, request *pdpb.GetRegionRequest) (*pdpb.GetRegionResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetPrevRegion(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetRegionResponse), err } rc := s.GetRaftCluster() @@ -1008,18 +981,13 @@ func (s *GrpcServer) GetPrevRegion(ctx context.Context, request *pdpb.GetRegionR // GetRegionByID implements gRPC PDServer. func (s *GrpcServer) GetRegionByID(ctx context.Context, request *pdpb.GetRegionByIDRequest) (*pdpb.GetRegionResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetRegionByID(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetRegionResponse), err } rc := s.GetRaftCluster() @@ -1041,18 +1009,13 @@ func (s *GrpcServer) GetRegionByID(ctx context.Context, request *pdpb.GetRegionB // ScanRegions implements gRPC PDServer. func (s *GrpcServer) ScanRegions(ctx context.Context, request *pdpb.ScanRegionsRequest) (*pdpb.ScanRegionsResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).ScanRegions(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.ScanRegionsResponse), nil } rc := s.GetRaftCluster() @@ -1081,18 +1044,13 @@ func (s *GrpcServer) ScanRegions(ctx context.Context, request *pdpb.ScanRegionsR // AskSplit implements gRPC PDServer. func (s *GrpcServer) AskSplit(ctx context.Context, request *pdpb.AskSplitRequest) (*pdpb.AskSplitResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).AskSplit(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.AskSplitResponse), err } rc := s.GetRaftCluster() @@ -1119,18 +1077,13 @@ func (s *GrpcServer) AskSplit(ctx context.Context, request *pdpb.AskSplitRequest // AskBatchSplit implements gRPC PDServer. func (s *GrpcServer) AskBatchSplit(ctx context.Context, request *pdpb.AskBatchSplitRequest) (*pdpb.AskBatchSplitResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).AskBatchSplit(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.AskBatchSplitResponse), err } rc := s.GetRaftCluster() @@ -1161,18 +1114,13 @@ func (s *GrpcServer) AskBatchSplit(ctx context.Context, request *pdpb.AskBatchSp // ReportSplit implements gRPC PDServer. func (s *GrpcServer) ReportSplit(ctx context.Context, request *pdpb.ReportSplitRequest) (*pdpb.ReportSplitResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).ReportSplit(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.ReportSplitResponse), err } rc := s.GetRaftCluster() @@ -1191,18 +1139,13 @@ func (s *GrpcServer) ReportSplit(ctx context.Context, request *pdpb.ReportSplitR // ReportBatchSplit implements gRPC PDServer. func (s *GrpcServer) ReportBatchSplit(ctx context.Context, request *pdpb.ReportBatchSplitRequest) (*pdpb.ReportBatchSplitResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).ReportBatchSplit(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.ReportBatchSplitResponse), err } rc := s.GetRaftCluster() @@ -1222,18 +1165,13 @@ func (s *GrpcServer) ReportBatchSplit(ctx context.Context, request *pdpb.ReportB // GetClusterConfig implements gRPC PDServer. func (s *GrpcServer) GetClusterConfig(ctx context.Context, request *pdpb.GetClusterConfigRequest) (*pdpb.GetClusterConfigResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetClusterConfig(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetClusterConfigResponse), err } rc := s.GetRaftCluster() @@ -1248,18 +1186,13 @@ func (s *GrpcServer) GetClusterConfig(ctx context.Context, request *pdpb.GetClus // PutClusterConfig implements gRPC PDServer. func (s *GrpcServer) PutClusterConfig(ctx context.Context, request *pdpb.PutClusterConfigRequest) (*pdpb.PutClusterConfigResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).PutClusterConfig(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.PutClusterConfigResponse), err } rc := s.GetRaftCluster() @@ -1280,18 +1213,13 @@ func (s *GrpcServer) PutClusterConfig(ctx context.Context, request *pdpb.PutClus // ScatterRegion implements gRPC PDServer. func (s *GrpcServer) ScatterRegion(ctx context.Context, request *pdpb.ScatterRegionRequest) (*pdpb.ScatterRegionResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).ScatterRegion(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.ScatterRegionResponse), err } rc := s.GetRaftCluster() @@ -1352,18 +1280,13 @@ func (s *GrpcServer) ScatterRegion(ctx context.Context, request *pdpb.ScatterReg // GetGCSafePoint implements gRPC PDServer. func (s *GrpcServer) GetGCSafePoint(ctx context.Context, request *pdpb.GetGCSafePointRequest) (*pdpb.GetGCSafePointResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetGCSafePoint(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetGCSafePointResponse), err } rc := s.GetRaftCluster() @@ -1397,18 +1320,13 @@ func (s *GrpcServer) SyncRegions(stream pdpb.PD_SyncRegionsServer) error { // UpdateGCSafePoint implements gRPC PDServer. func (s *GrpcServer) UpdateGCSafePoint(ctx context.Context, request *pdpb.UpdateGCSafePointRequest) (*pdpb.UpdateGCSafePointResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).UpdateGCSafePoint(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.UpdateGCSafePointResponse), err } rc := s.GetRaftCluster() @@ -1448,19 +1366,13 @@ func (s *GrpcServer) UpdateGCSafePoint(ctx context.Context, request *pdpb.Update func (s *GrpcServer) UpdateServiceGCSafePoint(ctx context.Context, request *pdpb.UpdateServiceGCSafePointRequest) (*pdpb.UpdateServiceGCSafePointResponse, error) { s.serviceSafePointLock.Lock() defer s.serviceSafePointLock.Unlock() - - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).UpdateServiceGCSafePoint(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.UpdateServiceGCSafePointResponse), err } rc := s.GetRaftCluster() @@ -1519,18 +1431,13 @@ func (s *GrpcServer) UpdateServiceGCSafePoint(ctx context.Context, request *pdpb // GetOperator gets information about the operator belonging to the specify region. func (s *GrpcServer) GetOperator(ctx context.Context, request *pdpb.GetOperatorRequest) (*pdpb.GetOperatorResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).GetOperator(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.GetOperatorResponse), err } rc := s.GetRaftCluster() @@ -1601,7 +1508,7 @@ var mockLocalAllocatorLeaderChangeFlag = false // SyncMaxTS will check whether MaxTS is the biggest one among all Local TSOs this PD is holding when skipCheck is set, // and write it into all Local TSO Allocators then if it's indeed the biggest one. -func (s *GrpcServer) SyncMaxTS(ctx context.Context, request *pdpb.SyncMaxTSRequest) (*pdpb.SyncMaxTSResponse, error) { +func (s *GrpcServer) SyncMaxTS(_ context.Context, request *pdpb.SyncMaxTSRequest) (*pdpb.SyncMaxTSResponse, error) { if err := s.validateInternalRequest(request.GetHeader(), true); err != nil { return nil, err } @@ -1684,19 +1591,15 @@ func (s *GrpcServer) SyncMaxTS(ctx context.Context, request *pdpb.SyncMaxTSReque // SplitRegions split regions by the given split keys func (s *GrpcServer) SplitRegions(ctx context.Context, request *pdpb.SplitRegionsRequest) (*pdpb.SplitRegionsResponse, error) { - forwardedHost := getForwardedHost(ctx) - if !s.isLocalRequest(forwardedHost) { - client, err := s.getDelegateClient(ctx, forwardedHost) - if err != nil { - return nil, err - } - ctx = grpcutil.ResetForwardContext(ctx) + fn := func(ctx context.Context, client *grpc.ClientConn) (interface{}, error) { return pdpb.NewPDClient(client).SplitRegions(ctx, request) } - - if err := s.validateRequest(request.GetHeader()); err != nil { + if rsp, err := s.unaryMiddleware(ctx, request.GetHeader(), fn); err != nil { return nil, err + } else if rsp != nil { + return rsp.(*pdpb.SplitRegionsResponse), err } + finishedPercentage, newRegionIDs := s.cluster.GetRegionSplitter().SplitRegions(ctx, request.GetSplitKeys(), int(request.GetRetryLimit())) return &pdpb.SplitRegionsResponse{ Header: s.header(), @@ -1706,7 +1609,7 @@ func (s *GrpcServer) SplitRegions(ctx context.Context, request *pdpb.SplitRegion } // SplitAndScatterRegions split regions by the given split keys, and scatter regions -func (s *GrpcServer) SplitAndScatterRegions(ctx context.Context, request *pdpb.SplitAndScatterRegionsRequest) (*pdpb.SplitAndScatterRegionsResponse, error) { +func (s *GrpcServer) SplitAndScatterRegions(_ context.Context, _ *pdpb.SplitAndScatterRegionsRequest) (*pdpb.SplitAndScatterRegionsResponse, error) { panic("unimplemented") } @@ -1872,7 +1775,7 @@ func checkStream(streamCtx context.Context, cancel context.CancelFunc, done chan const globalConfigPath = "/global/config/" // StoreGlobalConfig store global config into etcd by transaction -func (s *GrpcServer) StoreGlobalConfig(ctx context.Context, request *pdpb.StoreGlobalConfigRequest) (*pdpb.StoreGlobalConfigResponse, error) { +func (s *GrpcServer) StoreGlobalConfig(_ context.Context, request *pdpb.StoreGlobalConfigRequest) (*pdpb.StoreGlobalConfigResponse, error) { ops := make([]clientv3.Op, len(request.Changes)) for i, item := range request.Changes { name := globalConfigPath + item.GetName() @@ -1911,7 +1814,7 @@ func (s *GrpcServer) LoadGlobalConfig(ctx context.Context, request *pdpb.LoadGlo // WatchGlobalConfig if the connection of WatchGlobalConfig is end // or stoped by whatever reason // just reconnect to it. -func (s *GrpcServer) WatchGlobalConfig(request *pdpb.WatchGlobalConfigRequest, server pdpb.PD_WatchGlobalConfigServer) error { +func (s *GrpcServer) WatchGlobalConfig(_ *pdpb.WatchGlobalConfigRequest, server pdpb.PD_WatchGlobalConfigServer) error { ctx, cancel := context.WithCancel(s.Context()) defer cancel() err := s.sendAllGlobalConfig(ctx, server) diff --git a/server/schedule/labeler/labeler.go b/server/schedule/labeler/labeler.go index dbee44305800..88b14f2b523b 100644 --- a/server/schedule/labeler/labeler.go +++ b/server/schedule/labeler/labeler.go @@ -15,9 +15,11 @@ package labeler import ( + "context" "encoding/json" "strings" "sync" + "time" "github.com/pingcap/log" "github.com/tikv/pd/pkg/errs" @@ -33,21 +35,72 @@ type RegionLabeler struct { sync.RWMutex labelRules map[string]*LabelRule rangeList rangelist.List // sorted LabelRules of the type `KeyRange` + ctx context.Context + minExpire *time.Time } // NewRegionLabeler creates a Labeler instance. -func NewRegionLabeler(storage endpoint.RuleStorage) (*RegionLabeler, error) { +func NewRegionLabeler(ctx context.Context, storage endpoint.RuleStorage, gcInterval time.Duration) (*RegionLabeler, error) { l := &RegionLabeler{ storage: storage, labelRules: make(map[string]*LabelRule), + ctx: ctx, + minExpire: nil, } if err := l.loadRules(); err != nil { return nil, err } + go l.doGC(gcInterval) return l, nil } +func (l *RegionLabeler) doGC(gcInterval time.Duration) { + ticker := time.NewTicker(gcInterval) + defer ticker.Stop() + for { + select { + case <-ticker.C: + l.checkAndClearExpiredLabels() + log.Debug("RegionLabeler GC") + case <-l.ctx.Done(): + log.Info("RegionLabeler GC stopped") + return + } + } +} + +func (l *RegionLabeler) checkAndClearExpiredLabels() { + now := time.Now() + l.Lock() + defer l.Unlock() + + if l.minExpire == nil || l.minExpire.After(now) { + return + } + var err error + deleted := false + + for key, rule := range l.labelRules { + if !rule.checkAndRemoveExpireLabels(now) { + continue + } + if len(rule.Labels) == 0 { + err = l.storage.DeleteRegionRule(key) + delete(l.labelRules, key) + deleted = true + } else { + err = l.storage.SaveRegionRule(key, rule) + } + if err != nil { + log.Error("failed to save rule expired label rule", zap.String("rule-key", key), zap.Error(err)) + } + } + if deleted { + l.buildRangeList() + } +} + func (l *RegionLabeler) loadRules() error { var toDelete []string err := l.storage.LoadRegionRules(func(k, v string) { @@ -78,7 +131,11 @@ func (l *RegionLabeler) loadRules() error { func (l *RegionLabeler) buildRangeList() { builder := rangelist.NewBuilder() + l.minExpire = nil for _, rule := range l.labelRules { + if l.minExpire == nil || rule.expireBefore(*l.minExpire) { + l.minExpire = rule.minExpire + } if rule.RuleType == KeyRange { rs := rule.Data.([]*KeyRangeRule) for _, r := range rs { @@ -98,6 +155,7 @@ func (l *RegionLabeler) GetSplitKeys(start, end []byte) [][]byte { // GetAllLabelRules returns all the rules. func (l *RegionLabeler) GetAllLabelRules() []*LabelRule { + l.checkAndClearExpiredLabels() l.RLock() defer l.RUnlock() rules := make([]*LabelRule, 0, len(l.labelRules)) @@ -109,11 +167,10 @@ func (l *RegionLabeler) GetAllLabelRules() []*LabelRule { // GetLabelRules returns the rules that match the given ids. func (l *RegionLabeler) GetLabelRules(ids []string) ([]*LabelRule, error) { - l.RLock() - defer l.RUnlock() + now := time.Now() rules := make([]*LabelRule, 0, len(ids)) for _, id := range ids { - if rule, ok := l.labelRules[id]; ok { + if rule := l.getAndCheckRule(id, now); rule != nil { rules = append(rules, rule) } } @@ -122,9 +179,26 @@ func (l *RegionLabeler) GetLabelRules(ids []string) ([]*LabelRule, error) { // GetLabelRule returns the Rule with the same ID. func (l *RegionLabeler) GetLabelRule(id string) *LabelRule { - l.RLock() - defer l.RUnlock() - return l.labelRules[id] + return l.getAndCheckRule(id, time.Now()) +} + +func (l *RegionLabeler) getAndCheckRule(id string, now time.Time) *LabelRule { + l.Lock() + defer l.Unlock() + rule, ok := l.labelRules[id] + if !ok { + return nil + } + if !rule.checkAndRemoveExpireLabels(now) { + return rule + } + if len(rule.Labels) == 0 { + l.storage.DeleteRule(id) + delete(l.labelRules, id) + return nil + } + l.storage.SaveRegionRule(id, rule) + return rule } // SetLabelRule inserts or updates a LabelRule. @@ -196,6 +270,7 @@ func (l *RegionLabeler) Patch(patch LabelRulePatch) error { func (l *RegionLabeler) GetRegionLabel(region *core.RegionInfo, key string) string { l.RLock() defer l.RUnlock() + now := time.Now() value, index := "", -1 // search ranges if i, data := l.rangeList.GetData(region.GetStartKey(), region.GetEndKey()); i != -1 { @@ -205,6 +280,9 @@ func (l *RegionLabeler) GetRegionLabel(region *core.RegionInfo, key string) stri continue } for _, l := range r.Labels { + if l.expireBefore(now) { + continue + } if l.Key == key { value, index = l.Value, r.Index } @@ -230,12 +308,15 @@ func (l *RegionLabeler) GetRegionLabels(region *core.RegionInfo) []*RegionLabel index int } labels := make(map[string]valueIndex) - + now := time.Now() // search ranges if i, data := l.rangeList.GetData(region.GetStartKey(), region.GetEndKey()); i != -1 { for _, rule := range data { r := rule.(*LabelRule) for _, l := range r.Labels { + if l.expireBefore(now) { + continue + } if old, ok := labels[l.Key]; !ok || old.index < r.Index { labels[l.Key] = valueIndex{l.Value, r.Index} } diff --git a/server/schedule/labeler/labeler_test.go b/server/schedule/labeler/labeler_test.go index 9e108e850ea2..b963bb8b5bca 100644 --- a/server/schedule/labeler/labeler_test.go +++ b/server/schedule/labeler/labeler_test.go @@ -15,10 +15,13 @@ package labeler import ( + "context" "encoding/hex" "encoding/json" + "fmt" "sort" "testing" + "time" . "github.com/pingcap/check" "github.com/tikv/pd/server/core" @@ -40,7 +43,7 @@ type testLabelerSuite struct { func (s *testLabelerSuite) SetUpTest(c *C) { s.store = storage.NewStorageWithMemoryBackend() var err error - s.labeler, err = NewRegionLabeler(s.store) + s.labeler, err = NewRegionLabeler(context.Background(), s.store, time.Millisecond*10) c.Assert(err, IsNil) } @@ -137,7 +140,9 @@ func (s *testLabelerSuite) TestGetSetRule(c *C) { c.Assert(err, IsNil) allRules = s.labeler.GetAllLabelRules() sort.Slice(allRules, func(i, j int) bool { return allRules[i].ID < allRules[j].ID }) - c.Assert(allRules, DeepEquals, rules[1:]) + for id, rule := range allRules { + expectSameRules(c, rule, rules[id+1]) + } } func (s *testLabelerSuite) TestIndex(c *C) { @@ -189,12 +194,34 @@ func (s *testLabelerSuite) TestSaveLoadRule(c *C) { c.Assert(err, IsNil) } - labeler, err := NewRegionLabeler(s.store) + labeler, err := NewRegionLabeler(context.Background(), s.store, time.Millisecond*100) c.Assert(err, IsNil) for _, r := range rules { r2 := labeler.GetLabelRule(r.ID) - c.Assert(r2, DeepEquals, r) + expectSameRules(c, r2, r) + } +} + +func expectSameRegionLabels(c *C, r1, r2 *RegionLabel) { + r1.checkAndAdjustExpire() + r2.checkAndAdjustExpire() + if len(r1.TTL) == 0 { + c.Assert(r2, DeepEquals, r1) + } + + r2.StartAt = r1.StartAt + r2.checkAndAdjustExpire() + + c.Assert(r2, DeepEquals, r1) +} + +func expectSameRules(c *C, r1, r2 *LabelRule) { + c.Assert(r1.Labels, HasLen, len(r2.Labels)) + for id := 0; id < len(r1.Labels); id++ { + expectSameRegionLabels(c, &r1.Labels[id], &r2.Labels[id]) } + + c.Assert(r2, DeepEquals, r1) } func (s *testLabelerSuite) TestKeyRange(c *C) { @@ -234,6 +261,104 @@ func (s *testLabelerSuite) TestKeyRange(c *C) { } } +func (s *testLabelerSuite) TestLabelerRuleTTL(c *C) { + rules := []*LabelRule{ + { + ID: "rule1", + Labels: []RegionLabel{ + {Key: "k1", Value: "v1"}, + }, + RuleType: "key-range", + Data: makeKeyRanges("1234", "5678")}, + { + ID: "rule2", + Labels: []RegionLabel{ + {Key: "k2", Value: "v2", TTL: "5ms"}, // would expired first.}, + }, + RuleType: "key-range", + + Data: makeKeyRanges("1234", "5678")}, + + { + ID: "rule3", + Labels: []RegionLabel{{Key: "k3", Value: "v3", TTL: "1h"}}, + RuleType: "key-range", + Data: makeKeyRanges("1234", "5678")}, + } + + start, _ := hex.DecodeString("1234") + end, _ := hex.DecodeString("5678") + region := core.NewTestRegionInfo(start, end) + // the region has no lable rule at the beginning. + c.Assert(s.labeler.GetRegionLabels(region), HasLen, 0) + + // set rules for the region. + for _, r := range rules { + err := s.labeler.SetLabelRule(r) + c.Assert(err, IsNil) + } + + // get rule with "rule2" and wait until it expired. + for s.labeler.GetLabelRule("rule2") != nil { + labels := s.labeler.GetRegionLabels(region) + if len(labels) == 2 { + break + } + time.Sleep(time.Millisecond * 5) + } + c.Assert(s.labeler.GetRegionLabel(region, "k2"), Equals, "") + // rule2 should be timeout first. + c.Assert(s.labeler.GetLabelRule("rule2"), IsNil) + c.Assert(s.labeler.GetLabelRule("rule3"), NotNil) + c.Assert(s.labeler.GetLabelRule("rule1"), NotNil) +} + +func (s *testLabelerSuite) TestGC(c *C) { + // set gcInterval to 1 hour. + store := storage.NewStorageWithMemoryBackend() + labeler, err := NewRegionLabeler(context.Background(), store, time.Hour) + c.Assert(err, IsNil) + ttls := []string{"1ms", "1ms", "1ms", "5ms", "5ms", "10ms", "1h", "24h"} + start, _ := hex.DecodeString("1234") + end, _ := hex.DecodeString("5678") + region := core.NewTestRegionInfo(start, end) + // the region has no lable rule at the beginning. + c.Assert(labeler.GetRegionLabels(region), HasLen, 0) + + labels := []RegionLabel{} + for id, ttl := range ttls { + labels = append(labels, RegionLabel{Key: fmt.Sprintf("k%d", id), Value: fmt.Sprintf("v%d", id), TTL: ttl}) + rule := &LabelRule{ + ID: fmt.Sprintf("rule%d", id), + Labels: labels, + RuleType: "key-range", + Data: makeKeyRanges("1234", "5678")} + err := labeler.SetLabelRule(rule) + c.Assert(err, IsNil) + } + + c.Assert(labeler.labelRules, HasLen, len(ttls)) + + // check all rules unitl some rule expired. + for { + time.Sleep(time.Millisecond * 5) + labels := labeler.GetRegionLabels(region) + if len(labels) != len(ttls) { + break + } + } + + // no rule was cleared because the gc interval is big. + c.Assert(labeler.labelRules, HasLen, len(ttls)) + + labeler.checkAndClearExpiredLabels() + + labeler.RLock() + currentRuleLen := len(labeler.labelRules) + labeler.RUnlock() + c.Assert(currentRuleLen <= 5, IsTrue) +} + func makeKeyRanges(keys ...string) []interface{} { var res []interface{} for i := 0; i < len(keys); i += 2 { diff --git a/server/schedule/labeler/rule_test.go b/server/schedule/labeler/rule_test.go new file mode 100644 index 000000000000..c1b8969393d7 --- /dev/null +++ b/server/schedule/labeler/rule_test.go @@ -0,0 +1,60 @@ +// Copyright 2022 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package labeler + +import ( + "encoding/json" + "time" + + . "github.com/pingcap/check" +) + +var _ = Suite(&testRuleSuite{}) + +type testRuleSuite struct{} + +func (s *testLabelerSuite) TestRegionLabelTTL(c *C) { + label := RegionLabel{Key: "k1", Value: "v1"} + + // test label with no ttl. + err := label.checkAndAdjustExpire() + c.Assert(err, IsNil) + c.Assert(label.StartAt, HasLen, 0) + c.Assert(label.expire, IsNil) + + // test rule with illegal ttl. + label.TTL = "ttl" + err = label.checkAndAdjustExpire() + c.Assert(err, NotNil) + + // test legal rule with ttl + label.TTL = "10h10m10s10ms" + err = label.checkAndAdjustExpire() + c.Assert(err, IsNil) + c.Assert(len(label.StartAt) > 0, IsTrue) + c.Assert(label.expireBefore(time.Now().Add(time.Hour)), IsFalse) + c.Assert(label.expireBefore(time.Now().Add(24*time.Hour)), IsTrue) + + // test legal rule with ttl, rule unmarshal from json. + data, err := json.Marshal(label) + c.Assert(err, IsNil) + var label2 RegionLabel + err = json.Unmarshal(data, &label2) + c.Assert(err, IsNil) + c.Assert(label2.StartAt, Equals, label.StartAt) + c.Assert(label2.TTL, Equals, label.TTL) + label2.checkAndAdjustExpire() + c.Assert(label.expire.Format(time.UnixDate), Equals, label2.expire.Format(time.UnixDate)) +} diff --git a/server/schedule/labeler/rules.go b/server/schedule/labeler/rules.go index eaa1b294e02a..bb7f408b2209 100644 --- a/server/schedule/labeler/rules.go +++ b/server/schedule/labeler/rules.go @@ -19,6 +19,7 @@ import ( "encoding/hex" "fmt" "reflect" + "time" "github.com/pingcap/log" "github.com/tikv/pd/pkg/errs" @@ -28,18 +29,22 @@ import ( // RegionLabel is the label of a region. // NOTE: This type is exported by HTTP API. Please pay more attention when modifying it. type RegionLabel struct { - Key string `json:"key"` - Value string `json:"value"` + Key string `json:"key"` + Value string `json:"value"` + TTL string `json:"ttl,omitempty"` + StartAt string `json:"start_at,omitempty"` + expire *time.Time } // LabelRule is the rule to assign labels to a region. // NOTE: This type is exported by HTTP API. Please pay more attention when modifying it. type LabelRule struct { - ID string `json:"id"` - Index int `json:"index"` - Labels []RegionLabel `json:"labels"` - RuleType string `json:"rule_type"` - Data interface{} `json:"data"` + ID string `json:"id"` + Index int `json:"index"` + Labels []RegionLabel `json:"labels"` + RuleType string `json:"rule_type"` + Data interface{} `json:"data"` + minExpire *time.Time } const ( @@ -68,6 +73,57 @@ type LabelRulePatch struct { DeleteRules []string `json:"deletes"` } +func (l *RegionLabel) expireBefore(t time.Time) bool { + if l.expire == nil { + return false + } + return l.expire.Before(t) +} + +func (l *RegionLabel) checkAndAdjustExpire() (err error) { + if len(l.TTL) == 0 { + l.expire = nil + return + } + ttl, err := time.ParseDuration(l.TTL) + if err != nil { + return err + } + var startAt time.Time + if len(l.StartAt) == 0 { + startAt = time.Now() + l.StartAt = startAt.Format(time.UnixDate) + } else { + startAt, err = time.Parse(time.UnixDate, l.StartAt) + if err != nil { + return err + } + } + expire := startAt.Add(ttl) + l.expire = &expire + return nil +} + +func (rule *LabelRule) checkAndRemoveExpireLabels(now time.Time) bool { + labels := make([]RegionLabel, 0) + rule.minExpire = nil + for _, l := range rule.Labels { + if l.expireBefore(now) { + continue + } + labels = append(labels, l) + if rule.minExpire == nil || l.expireBefore(*rule.minExpire) { + rule.minExpire = l.expire + } + } + + if len(labels) == len(rule.Labels) { + return false + } + rule.Labels = labels + return true +} + func (rule *LabelRule) checkAndAdjust() error { if rule.ID == "" { return errs.ErrRegionRuleContent.FastGenByArgs("empty rule id") @@ -75,13 +131,21 @@ func (rule *LabelRule) checkAndAdjust() error { if len(rule.Labels) == 0 { return errs.ErrRegionRuleContent.FastGenByArgs("no region labels") } - for _, l := range rule.Labels { + for id, l := range rule.Labels { if l.Key == "" { return errs.ErrRegionRuleContent.FastGenByArgs("empty region label key") } if l.Value == "" { return errs.ErrRegionRuleContent.FastGenByArgs("empty region label value") } + if err := rule.Labels[id].checkAndAdjustExpire(); err != nil { + err := fmt.Sprintf("region label with invalid ttl info %v", err) + return errs.ErrRegionRuleContent.FastGenByArgs(err) + } + } + rule.checkAndRemoveExpireLabels(time.Now()) + if len(rule.Labels) == 0 { + return errs.ErrRegionRuleContent.FastGenByArgs("region label with expired ttl") } // TODO: change it to switch statement once we support more types. @@ -94,6 +158,13 @@ func (rule *LabelRule) checkAndAdjust() error { return errs.ErrRegionRuleContent.FastGenByArgs(fmt.Sprintf("invalid rule type: %s", rule.RuleType)) } +func (rule *LabelRule) expireBefore(t time.Time) bool { + if rule.minExpire == nil { + return false + } + return rule.minExpire.Before(t) +} + // initKeyRangeRulesFromLabelRuleData init and adjust []KeyRangeRule from `LabelRule.Data`` func initKeyRangeRulesFromLabelRuleData(data interface{}) ([]*KeyRangeRule, error) { rules, ok := data.([]interface{}) diff --git a/tests/client/go.mod b/tests/client/go.mod index b258d794a760..1fc23575b2a1 100644 --- a/tests/client/go.mod +++ b/tests/client/go.mod @@ -3,11 +3,11 @@ module github.com/tikv/pd/tests/client go 1.16 require ( - github.com/gogo/protobuf v1.3.1 + github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.5.2 // indirect github.com/pingcap/check v0.0.0-20211026125417-57bd13f7b5f0 github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 - github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a + github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748 github.com/tikv/pd v0.0.0-00010101000000-000000000000 github.com/tikv/pd/client v0.0.0-00010101000000-000000000000 go.etcd.io/etcd v0.5.0-alpha.5.0.20191023171146-3cf2f69b5738 diff --git a/tests/client/go.sum b/tests/client/go.sum index 39ec14f51657..83705bde59a1 100644 --- a/tests/client/go.sum +++ b/tests/client/go.sum @@ -169,8 +169,9 @@ github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v0.0.0-20180717141946-636bf0302bc9/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -218,8 +219,9 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -300,6 +302,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -404,9 +407,8 @@ github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 h1:C3N3itkduZXDZ github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew= github.com/pingcap/kvproto v0.0.0-20191211054548-3c6b38ea5107/go.mod h1:WWLmULLO7l8IOcQG+t+ItJ3fEcrL5FxF0Wu+HrMy26w= github.com/pingcap/kvproto v0.0.0-20200411081810-b85805c9476c/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= -github.com/pingcap/kvproto v0.0.0-20220302110454-c696585a961b/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= -github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a h1:0ZnJ8JPtPVGG3qF1G9Kz0NYDEj8BraNEJeQlmwUF6BA= -github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748 h1:i4MBe1zGq9/r3BH6rTRunizi4T59fpNk8hvBCrB5UAY= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM= @@ -518,12 +520,15 @@ github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7 github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/thoas/go-funk v0.8.0 h1:JP9tKSvnpFVclYgDM0Is7FD9M4fhPvqA0s0BsXmzSRQ= github.com/thoas/go-funk v0.8.0/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= -github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= -github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= +github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E= +github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= @@ -552,6 +557,7 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= @@ -620,6 +626,7 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -642,6 +649,7 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= @@ -730,6 +738,8 @@ golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200225230052-807dcd883420/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= diff --git a/tests/server/global_config/global_config_test.go b/tests/server/global_config/global_config_test.go index eb738cd2fbdb..cc4b73b8a561 100644 --- a/tests/server/global_config/global_config_test.go +++ b/tests/server/global_config/global_config_test.go @@ -235,11 +235,3 @@ func (s *GlobalConfigTestSuite) TestClientWatch(c *C) { } } } - -func (s *GlobalConfigTestSuite) TestClientWatchTimeout(c *C) { - ctx, cancel := context.WithCancel(s.server.Context()) - wc, _ := s.watchGlobalConfig(ctx) - cancel() - _, opened := <-wc - c.Assert(opened, Equals, false) -} diff --git a/tools/pd-tso-bench/go.sum b/tools/pd-tso-bench/go.sum index 0cf5621abd8e..1e0eaf8b258c 100644 --- a/tools/pd-tso-bench/go.sum +++ b/tools/pd-tso-bench/go.sum @@ -43,8 +43,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -81,7 +81,7 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -108,10 +108,8 @@ github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c h1:xpW9bvK+HuuTm github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 h1:C3N3itkduZXDZFh4N3vQ5HEtld3S+Y+StULhWVvumU0= github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew= -github.com/pingcap/kvproto v0.0.0-20220302110454-c696585a961b h1:/OL63rEIcCEivpgTLCkhxVbO3RMxSuHtsKWSgDwS6oY= -github.com/pingcap/kvproto v0.0.0-20220302110454-c696585a961b/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= -github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a h1:0ZnJ8JPtPVGG3qF1G9Kz0NYDEj8BraNEJeQlmwUF6BA= -github.com/pingcap/kvproto v0.0.0-20220309094445-a78dc9fdb89a/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748 h1:i4MBe1zGq9/r3BH6rTRunizi4T59fpNk8hvBCrB5UAY= +github.com/pingcap/kvproto v0.0.0-20220330070404-8c4cd3f93748/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee h1:VO2t6IBpfvW34TdtD/G10VvnGqjLic1jzOuHjUb5VqM= github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= @@ -154,6 +152,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -190,6 +190,8 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -201,8 +203,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -213,6 +217,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -225,6 +230,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -238,7 +244,6 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -249,6 +254,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191107010934-f79515f33823/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=