diff --git a/build/BUILD.bazel b/build/BUILD.bazel index 23cf263d525e3..2b6bc8cf215f2 100644 --- a/build/BUILD.bazel +++ b/build/BUILD.bazel @@ -123,6 +123,7 @@ nogo( "//build/linter/asciicheck:asciicheck", "//build/linter/bodyclose:bodyclose", "//build/linter/durationcheck:durationcheck", + "//build/linter/etcdconfig:etcdconfig", "//build/linter/exportloopref:exportloopref", "//build/linter/forcetypeassert:forcetypeassert", "//build/linter/gofmt:gofmt", diff --git a/build/linter/etcdconfig/BUILD.bazel b/build/linter/etcdconfig/BUILD.bazel new file mode 100644 index 0000000000000..beff516fd4837 --- /dev/null +++ b/build/linter/etcdconfig/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "etcdconfig", + srcs = ["analyzer.go"], + importpath = "github.com/pingcap/tidb/build/linter/etcdconfig", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_x_tools//go/analysis", + "@org_golang_x_tools//go/analysis/passes/inspect", + ], +) diff --git a/build/linter/etcdconfig/analyzer.go b/build/linter/etcdconfig/analyzer.go new file mode 100644 index 0000000000000..566a920a2f10e --- /dev/null +++ b/build/linter/etcdconfig/analyzer.go @@ -0,0 +1,100 @@ +// Copyright 2022 PingCAP, Inc. +// +// 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 etcdconfig + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" +) + +// Analyzer is the analyzer struct of unconvert. +var Analyzer = &analysis.Analyzer{ + Name: "etcdconfig", + Doc: "Check necessary fields of etcd config", + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +const ( + configPackagePath = "go.etcd.io/etcd/client/v3" + configPackageName = "clientv3" + configStructName = "Config" +) + +// Adapted from https://github.com/mdempsky/unconvert/blob/beb68d938016d2dec1d1b078054f4d3db25f97be/unconvert.go#L371-L414. +func run(pass *analysis.Pass) (interface{}, error) { + for _, file := range pass.Files { + packageName := "" + for _, spec := range file.Imports { + if spec.Path.Value != "\""+configPackagePath+"\"" { + continue + } + if spec.Name != nil { + packageName = spec.Name.Name + } else { + packageName = configPackageName + } + } + if packageName == "" { + continue + } + + for _, decl := range file.Decls { + ast.Inspect(decl, func(n ast.Node) bool { + lit, ok := n.(*ast.CompositeLit) + if !ok { + return true + } + tp, ok := lit.Type.(*ast.SelectorExpr) + if !ok { + return true + } + litPackage, ok := tp.X.(*ast.Ident) + if !ok { + return true + } + if litPackage.Name != packageName { + return true + } + if tp.Sel.Name != configStructName { + return true + } + + found := false + for _, field := range lit.Elts { + kv, ok := field.(*ast.KeyValueExpr) + if !ok { + continue + } + key, ok := kv.Key.(*ast.Ident) + if !ok { + continue + } + if key.Name == "AutoSyncInterval" { + found = true + break + } + } + if !found { + pass.Reportf(lit.Pos(), "missing field AutoSyncInterval") + } + return true + }) + } + } + return nil, nil +} diff --git a/build/nogo_config.json b/build/nogo_config.json index ce3715232b472..4a0ee73f9e5bd 100644 --- a/build/nogo_config.json +++ b/build/nogo_config.json @@ -916,5 +916,12 @@ "/external/": "no need to vet third party code", ".*_generated\\.go$": "ignore generated code" } + }, + "etcdconfig": { + "exclude_files": { + "parser/parser.go": "parser/parser.go code", + ".*_test.go": "ignore test code", + "external/": "no need to vet third party code" + } } } diff --git a/dumpling/export/util.go b/dumpling/export/util.go index 6c7443a1bee84..9f75d487254e6 100644 --- a/dumpling/export/util.go +++ b/dumpling/export/util.go @@ -35,8 +35,9 @@ func getPdDDLIDs(pCtx context.Context, cli *clientv3.Client) ([]string, error) { func checkSameCluster(tctx *tcontext.Context, db *sql.DB, pdAddrs []string) (bool, error) { cli, err := clientv3.New(clientv3.Config{ - Endpoints: pdAddrs, - DialTimeout: defaultEtcdDialTimeOut, + Endpoints: pdAddrs, + DialTimeout: defaultEtcdDialTimeOut, + AutoSyncInterval: 30 * time.Second, }) if err != nil { return false, errors.Trace(err) diff --git a/util/etcd/etcd.go b/util/etcd/etcd.go index 6735adbb9c12a..175deeac11329 100644 --- a/util/etcd/etcd.go +++ b/util/etcd/etcd.go @@ -78,9 +78,10 @@ func NewClient(cli *clientv3.Client, root string) *Client { // NewClientFromCfg returns a wrapped etcd client func NewClientFromCfg(endpoints []string, dialTimeout time.Duration, root string, security *tls.Config) (*Client, error) { cli, err := clientv3.New(clientv3.Config{ - Endpoints: endpoints, - DialTimeout: dialTimeout, - TLS: security, + Endpoints: endpoints, + DialTimeout: dialTimeout, + TLS: security, + AutoSyncInterval: 30 * time.Second, }) if err != nil { return nil, errors.Trace(err)