From 2130e26d4f3a98347108373827d14c1f5a3c595c Mon Sep 17 00:00:00 2001 From: disksing Date: Wed, 27 Mar 2019 11:41:47 +0800 Subject: [PATCH] add code lint (#10) * add code lint Signed-off-by: disksing --- Makefile | 4 +++ examples/rawkv/rawkv.go | 2 +- examples/txnkv/txnkv.go | 5 ++-- metrics/metrics.go | 5 ---- rawkv/errors.go | 18 ------------- rawkv/rawkv.go | 60 ++++++++++++++++++++--------------------- rawkv/rawkv_test.go | 4 +-- retry/backoff.go | 2 +- txnkv/client.go | 20 +++++++++----- txnkv/kv/kv.go | 2 +- txnkv/txn.go | 19 +++++++++++++ 11 files changed, 74 insertions(+), 67 deletions(-) delete mode 100644 rawkv/errors.go diff --git a/Makefile b/Makefile index cd6112f1..c3458790 100644 --- a/Makefile +++ b/Makefile @@ -3,3 +3,7 @@ default: test: GO111MODULE=on go test ./... + +check: + GO111MODULE=off go get golang.org/x/lint/golint + GO111MODULE=on golint `go list ./...` diff --git a/examples/rawkv/rawkv.go b/examples/rawkv/rawkv.go index 8bbf3f9d..018a2fb0 100644 --- a/examples/rawkv/rawkv.go +++ b/examples/rawkv/rawkv.go @@ -21,7 +21,7 @@ import ( ) func main() { - cli, err := rawkv.NewRawKVClient([]string{"127.0.0.1:2379"}, config.Security{}) + cli, err := rawkv.NewClient([]string{"127.0.0.1:2379"}, config.Security{}) if err != nil { panic(err) } diff --git a/examples/txnkv/txnkv.go b/examples/txnkv/txnkv.go index 4144cd08..d32765e8 100644 --- a/examples/txnkv/txnkv.go +++ b/examples/txnkv/txnkv.go @@ -24,6 +24,7 @@ import ( "github.com/tikv/client-go/txnkv" ) +// KV represents a Key-Value pair. type KV struct { K, V []byte } @@ -33,14 +34,14 @@ func (kv KV) String() string { } var ( - client *txnkv.TxnClient + client *txnkv.Client pdAddr = flag.String("pd", "127.0.0.1:2379", "pd address") ) // Init initializes information. func initStore() { var err error - client, err = txnkv.NewTxnClient([]string{*pdAddr}, config.Security{}) + client, err = txnkv.NewClient([]string{*pdAddr}, config.Security{}) if err != nil { panic(err) } diff --git a/metrics/metrics.go b/metrics/metrics.go index fd4c823f..9a056656 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -15,11 +15,6 @@ package metrics import "github.com/prometheus/client_golang/prometheus" -const ( - LabelBatchRecvLoop = "batch-recv-loop" - LabelBatchSendLoop = "batch-send-loop" -) - // Client metrics. // TODO: Create new grafana page for the metrics. var ( diff --git a/rawkv/errors.go b/rawkv/errors.go deleted file mode 100644 index b664448b..00000000 --- a/rawkv/errors.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2018 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, -// See the License for the specific language governing permissions and -// limitations under the License. - -package rawkv - -import "github.com/pkg/errors" - -var ErrBodyMissing = errors.New("response body is missing") diff --git a/rawkv/rawkv.go b/rawkv/rawkv.go index aa89898b..e9150cb7 100644 --- a/rawkv/rawkv.go +++ b/rawkv/rawkv.go @@ -33,17 +33,17 @@ var ( ErrMaxScanLimitExceeded = errors.New("limit should be less than MaxRawKVScanLimit") ) -// RawKVClient is a client of TiKV server which is used as a key-value storage, +// Client is a rawkv client of TiKV server which is used as a key-value storage, // only GET/PUT/DELETE commands are supported. -type RawKVClient struct { +type Client struct { clusterID uint64 regionCache *locate.RegionCache pdClient pd.Client rpcClient rpc.Client } -// NewRawKVClient creates a client with PD cluster addrs. -func NewRawKVClient(pdAddrs []string, security config.Security) (*RawKVClient, error) { +// NewClient creates a client with PD cluster addrs. +func NewClient(pdAddrs []string, security config.Security) (*Client, error) { pdCli, err := pd.NewClient(pdAddrs, pd.SecurityOption{ CAPath: security.SSLCA, CertPath: security.SSLCert, @@ -52,7 +52,7 @@ func NewRawKVClient(pdAddrs []string, security config.Security) (*RawKVClient, e if err != nil { return nil, err } - return &RawKVClient{ + return &Client{ clusterID: pdCli.GetClusterID(context.TODO()), regionCache: locate.NewRegionCache(pdCli), pdClient: pdCli, @@ -61,18 +61,18 @@ func NewRawKVClient(pdAddrs []string, security config.Security) (*RawKVClient, e } // Close closes the client. -func (c *RawKVClient) Close() error { +func (c *Client) Close() error { c.pdClient.Close() return c.rpcClient.Close() } // ClusterID returns the TiKV cluster ID. -func (c *RawKVClient) ClusterID() uint64 { +func (c *Client) ClusterID() uint64 { return c.clusterID } // Get queries value with the key. When the key does not exist, it returns `nil, nil`. -func (c *RawKVClient) Get(key []byte) ([]byte, error) { +func (c *Client) Get(key []byte) ([]byte, error) { start := time.Now() defer func() { metrics.RawkvCmdHistogram.WithLabelValues("get").Observe(time.Since(start).Seconds()) }() @@ -88,7 +88,7 @@ func (c *RawKVClient) Get(key []byte) ([]byte, error) { } cmdResp := resp.RawGet if cmdResp == nil { - return nil, errors.WithStack(ErrBodyMissing) + return nil, errors.WithStack(rpc.ErrBodyMissing) } if cmdResp.GetError() != "" { return nil, errors.New(cmdResp.GetError()) @@ -100,7 +100,7 @@ func (c *RawKVClient) Get(key []byte) ([]byte, error) { } // BatchGet queries values with the keys. -func (c *RawKVClient) BatchGet(keys [][]byte) ([][]byte, error) { +func (c *Client) BatchGet(keys [][]byte) ([][]byte, error) { start := time.Now() defer func() { metrics.RawkvCmdHistogram.WithLabelValues("batch_get").Observe(time.Since(start).Seconds()) @@ -114,7 +114,7 @@ func (c *RawKVClient) BatchGet(keys [][]byte) ([][]byte, error) { cmdResp := resp.RawBatchGet if cmdResp == nil { - return nil, errors.WithStack(ErrBodyMissing) + return nil, errors.WithStack(rpc.ErrBodyMissing) } keyToValue := make(map[string][]byte, len(keys)) @@ -130,7 +130,7 @@ func (c *RawKVClient) BatchGet(keys [][]byte) ([][]byte, error) { } // Put stores a key-value pair to TiKV. -func (c *RawKVClient) Put(key, value []byte) error { +func (c *Client) Put(key, value []byte) error { start := time.Now() defer func() { metrics.RawkvCmdHistogram.WithLabelValues("put").Observe(time.Since(start).Seconds()) }() metrics.RawkvSizeHistogram.WithLabelValues("key").Observe(float64(len(key))) @@ -153,7 +153,7 @@ func (c *RawKVClient) Put(key, value []byte) error { } cmdResp := resp.RawPut if cmdResp == nil { - return errors.WithStack(ErrBodyMissing) + return errors.WithStack(rpc.ErrBodyMissing) } if cmdResp.GetError() != "" { return errors.New(cmdResp.GetError()) @@ -162,7 +162,7 @@ func (c *RawKVClient) Put(key, value []byte) error { } // BatchPut stores key-value pairs to TiKV. -func (c *RawKVClient) BatchPut(keys, values [][]byte) error { +func (c *Client) BatchPut(keys, values [][]byte) error { start := time.Now() defer func() { metrics.RawkvCmdHistogram.WithLabelValues("batch_put").Observe(time.Since(start).Seconds()) @@ -181,7 +181,7 @@ func (c *RawKVClient) BatchPut(keys, values [][]byte) error { } // Delete deletes a key-value pair from TiKV. -func (c *RawKVClient) Delete(key []byte) error { +func (c *Client) Delete(key []byte) error { start := time.Now() defer func() { metrics.RawkvCmdHistogram.WithLabelValues("delete").Observe(time.Since(start).Seconds()) }() @@ -197,7 +197,7 @@ func (c *RawKVClient) Delete(key []byte) error { } cmdResp := resp.RawDelete if cmdResp == nil { - return errors.WithStack(ErrBodyMissing) + return errors.WithStack(rpc.ErrBodyMissing) } if cmdResp.GetError() != "" { return errors.New(cmdResp.GetError()) @@ -206,7 +206,7 @@ func (c *RawKVClient) Delete(key []byte) error { } // BatchDelete deletes key-value pairs from TiKV -func (c *RawKVClient) BatchDelete(keys [][]byte) error { +func (c *Client) BatchDelete(keys [][]byte) error { start := time.Now() defer func() { metrics.RawkvCmdHistogram.WithLabelValues("batch_delete").Observe(time.Since(start).Seconds()) @@ -219,7 +219,7 @@ func (c *RawKVClient) BatchDelete(keys [][]byte) error { } cmdResp := resp.RawBatchDelete if cmdResp == nil { - return errors.WithStack(ErrBodyMissing) + return errors.WithStack(rpc.ErrBodyMissing) } if cmdResp.GetError() != "" { return errors.New(cmdResp.GetError()) @@ -228,7 +228,7 @@ func (c *RawKVClient) BatchDelete(keys [][]byte) error { } // DeleteRange deletes all key-value pairs in a range from TiKV -func (c *RawKVClient) DeleteRange(startKey []byte, endKey []byte) error { +func (c *Client) DeleteRange(startKey []byte, endKey []byte) error { start := time.Now() var err error defer func() { @@ -249,7 +249,7 @@ func (c *RawKVClient) DeleteRange(startKey []byte, endKey []byte) error { } cmdResp := resp.RawDeleteRange if cmdResp == nil { - return errors.WithStack(ErrBodyMissing) + return errors.WithStack(rpc.ErrBodyMissing) } if cmdResp.GetError() != "" { return errors.New(cmdResp.GetError()) @@ -265,7 +265,7 @@ func (c *RawKVClient) DeleteRange(startKey []byte, endKey []byte) error { // If you want to exclude the startKey or include the endKey, append a '\0' to the key. For example, to scan // (startKey, endKey], you can write: // `Scan(append(startKey, '\0'), append(endKey, '\0'), limit)`. -func (c *RawKVClient) Scan(startKey, endKey []byte, limit int) (keys [][]byte, values [][]byte, err error) { +func (c *Client) Scan(startKey, endKey []byte, limit int) (keys [][]byte, values [][]byte, err error) { start := time.Now() defer func() { metrics.RawkvCmdHistogram.WithLabelValues("raw_scan").Observe(time.Since(start).Seconds()) }() @@ -288,7 +288,7 @@ func (c *RawKVClient) Scan(startKey, endKey []byte, limit int) (keys [][]byte, v } cmdResp := resp.RawScan if cmdResp == nil { - return nil, nil, errors.WithStack(ErrBodyMissing) + return nil, nil, errors.WithStack(rpc.ErrBodyMissing) } for _, pair := range cmdResp.Kvs { keys = append(keys, pair.Key) @@ -302,7 +302,7 @@ func (c *RawKVClient) Scan(startKey, endKey []byte, limit int) (keys [][]byte, v return } -func (c *RawKVClient) sendReq(key []byte, req *rpc.Request) (*rpc.Response, *locate.KeyLocation, error) { +func (c *Client) sendReq(key []byte, req *rpc.Request) (*rpc.Response, *locate.KeyLocation, error) { bo := retry.NewBackoffer(context.Background(), retry.RawkvMaxBackoff) sender := rpc.NewRegionRequestSender(c.regionCache, c.rpcClient) for { @@ -329,7 +329,7 @@ func (c *RawKVClient) sendReq(key []byte, req *rpc.Request) (*rpc.Response, *loc } } -func (c *RawKVClient) sendBatchReq(bo *retry.Backoffer, keys [][]byte, cmdType rpc.CmdType) (*rpc.Response, error) { // split the keys +func (c *Client) sendBatchReq(bo *retry.Backoffer, keys [][]byte, cmdType rpc.CmdType) (*rpc.Response, error) { // split the keys groups, _, err := c.regionCache.GroupKeysByRegion(bo, keys) if err != nil { return nil, err @@ -376,7 +376,7 @@ func (c *RawKVClient) sendBatchReq(bo *retry.Backoffer, keys [][]byte, cmdType r return resp, firstError } -func (c *RawKVClient) doBatchReq(bo *retry.Backoffer, batch batch, cmdType rpc.CmdType) singleBatchResp { +func (c *Client) doBatchReq(bo *retry.Backoffer, batch batch, cmdType rpc.CmdType) singleBatchResp { var req *rpc.Request switch cmdType { case rpc.CmdRawBatchGet: @@ -426,7 +426,7 @@ func (c *RawKVClient) doBatchReq(bo *retry.Backoffer, batch batch, cmdType rpc.C case rpc.CmdRawBatchDelete: cmdResp := resp.RawBatchDelete if cmdResp == nil { - batchResp.err = errors.WithStack(ErrBodyMissing) + batchResp.err = errors.WithStack(rpc.ErrBodyMissing) return batchResp } if cmdResp.GetError() != "" { @@ -442,7 +442,7 @@ func (c *RawKVClient) doBatchReq(bo *retry.Backoffer, batch batch, cmdType rpc.C // If the given range spans over more than one regions, the actual endKey is the end of the first region. // We can't use sendReq directly, because we need to know the end of the region before we send the request // TODO: Is there any better way to avoid duplicating code with func `sendReq` ? -func (c *RawKVClient) sendDeleteRangeReq(startKey []byte, endKey []byte) (*rpc.Response, []byte, error) { +func (c *Client) sendDeleteRangeReq(startKey []byte, endKey []byte) (*rpc.Response, []byte, error) { bo := retry.NewBackoffer(context.Background(), retry.RawkvMaxBackoff) sender := rpc.NewRegionRequestSender(c.regionCache, c.rpcClient) for { @@ -483,7 +483,7 @@ func (c *RawKVClient) sendDeleteRangeReq(startKey []byte, endKey []byte) (*rpc.R } } -func (c *RawKVClient) sendBatchPut(bo *retry.Backoffer, keys, values [][]byte) error { +func (c *Client) sendBatchPut(bo *retry.Backoffer, keys, values [][]byte) error { keyToValue := make(map[string][]byte) for i, key := range keys { keyToValue[string(key)] = values[i] @@ -560,7 +560,7 @@ func appendBatches(batches []batch, regionID locate.RegionVerID, groupKeys [][]b return batches } -func (c *RawKVClient) doBatchPut(bo *retry.Backoffer, batch batch) error { +func (c *Client) doBatchPut(bo *retry.Backoffer, batch batch) error { kvPair := make([]*kvrpcpb.KvPair, 0, len(batch.keys)) for i, key := range batch.keys { kvPair = append(kvPair, &kvrpcpb.KvPair{Key: key, Value: batch.values[i]}) @@ -593,7 +593,7 @@ func (c *RawKVClient) doBatchPut(bo *retry.Backoffer, batch batch) error { cmdResp := resp.RawBatchPut if cmdResp == nil { - return errors.WithStack(ErrBodyMissing) + return errors.WithStack(rpc.ErrBodyMissing) } if cmdResp.GetError() != "" { return errors.New(cmdResp.GetError()) diff --git a/rawkv/rawkv_test.go b/rawkv/rawkv_test.go index 45f83949..af3f4770 100644 --- a/rawkv/rawkv_test.go +++ b/rawkv/rawkv_test.go @@ -32,7 +32,7 @@ func TestT(t *testing.T) { type testRawKVSuite struct { cluster *mocktikv.Cluster - client *RawKVClient + client *Client bo *retry.Backoffer } @@ -43,7 +43,7 @@ func (s *testRawKVSuite) SetUpTest(c *C) { mocktikv.BootstrapWithSingleStore(s.cluster) pdClient := mocktikv.NewPDClient(s.cluster) mvccStore := mocktikv.MustNewMVCCStore() - s.client = &RawKVClient{ + s.client = &Client{ clusterID: 0, regionCache: locate.NewRegionCache(pdClient), pdClient: pdClient, diff --git a/retry/backoff.go b/retry/backoff.go index ecfc8d7b..94b5f881 100644 --- a/retry/backoff.go +++ b/retry/backoff.go @@ -196,7 +196,7 @@ func (b *Backoffer) Backoff(typ BackoffType, err error) error { b.totalSleep += f(b.ctx) b.types = append(b.types, typ) - var startTs interface{} = "" + var startTs interface{} if ts := b.ctx.Value(txnStartKey); ts != nil { startTs = ts } diff --git a/txnkv/client.go b/txnkv/client.go index ee30df5a..50fc37c9 100644 --- a/txnkv/client.go +++ b/txnkv/client.go @@ -21,25 +21,29 @@ import ( "github.com/tikv/client-go/txnkv/store" ) -type TxnClient struct { +// Client is a transactional client of TiKV server. +type Client struct { tikvStore *store.TiKVStore } -func NewTxnClient(pdAddrs []string, security config.Security) (*TxnClient, error) { +// NewClient creates a client with PD addresses. +func NewClient(pdAddrs []string, security config.Security) (*Client, error) { tikvStore, err := store.NewStore(pdAddrs, security) if err != nil { return nil, err } - return &TxnClient{ + return &Client{ tikvStore: tikvStore, }, nil } -func (c *TxnClient) Close() error { +// Close stop the client. +func (c *Client) Close() error { return c.tikvStore.Close() } -func (c *TxnClient) Begin() (*Transaction, error) { +// Begin creates a transaction for read/write. +func (c *Client) Begin() (*Transaction, error) { ts, err := c.GetTS() if err != nil { return nil, err @@ -47,10 +51,12 @@ func (c *TxnClient) Begin() (*Transaction, error) { return c.BeginWithTS(ts), nil } -func (c *TxnClient) BeginWithTS(ts uint64) *Transaction { +// BeginWithTS creates a transaction which is normally readonly. +func (c *Client) BeginWithTS(ts uint64) *Transaction { return newTransaction(c.tikvStore, ts) } -func (c *TxnClient) GetTS() (uint64, error) { +// GetTS returns a latest timestamp. +func (c *Client) GetTS() (uint64, error) { return c.tikvStore.GetTimestampWithRetry(retry.NewBackoffer(context.TODO(), retry.TsoMaxBackoff)) } diff --git a/txnkv/kv/kv.go b/txnkv/kv/kv.go index 8aa68049..7e0aa8c8 100644 --- a/txnkv/kv/kv.go +++ b/txnkv/kv/kv.go @@ -40,7 +40,7 @@ type Retriever interface { // Iter creates an Iterator positioned on the first entry that k <= entry's key. // If such entry is not found, it returns an invalid Iterator with no error. // It yields only keys that < upperBound. If upperBound is nil, it means the upperBound is unbounded. - // The Iterator must be Closed after use. + // The Iterator must be closed after use. Iter(k key.Key, upperBound key.Key) (Iterator, error) // IterReverse creates a reversed Iterator positioned on the first entry which key is less than k. diff --git a/txnkv/txn.go b/txnkv/txn.go index 293b0c77..10eb0154 100644 --- a/txnkv/txn.go +++ b/txnkv/txn.go @@ -27,6 +27,7 @@ import ( "github.com/tikv/client-go/txnkv/store" ) +// Transaction is a key-value transaction. type Transaction struct { tikvStore *store.TiKVStore snapshot *store.TiKVSnapshot @@ -77,6 +78,7 @@ func (txn *Transaction) Get(k key.Key) ([]byte, error) { return ret, nil } +// BatchGet gets a batch of values from TiKV server. func (txn *Transaction) BatchGet(keys []key.Key) (map[string][]byte, error) { if txn.IsReadOnly() { return txn.snapshot.BatchGet(keys) @@ -109,6 +111,7 @@ func (txn *Transaction) BatchGet(keys []key.Key) (map[string][]byte, error) { return storageValues, nil } +// Set sets the value for key k as v into kv store. func (txn *Transaction) Set(k key.Key, v []byte) error { txn.setCnt++ return txn.us.Set(k, v) @@ -118,6 +121,10 @@ func (txn *Transaction) String() string { return fmt.Sprintf("txn-%d", txn.startTS) } +// Iter creates an Iterator positioned on the first entry that k <= entry's key. +// If such entry is not found, it returns an invalid Iterator with no error. +// It yields only keys that < upperBound. If upperBound is nil, it means the upperBound is unbounded. +// The Iterator must be closed after use. func (txn *Transaction) Iter(k key.Key, upperBound key.Key) (kv.Iterator, error) { metrics.TxnCmdCounter.WithLabelValues("seek").Inc() start := time.Now() @@ -137,15 +144,19 @@ func (txn *Transaction) IterReverse(k key.Key) (kv.Iterator, error) { return txn.us.IterReverse(k) } +// IsReadOnly returns if there are pending key-value to commit in the transaction. func (txn *Transaction) IsReadOnly() bool { return txn.us.GetMemBuffer().Len() == 0 && len(txn.lockKeys) == 0 } +// Delete removes the entry for key k from kv store. func (txn *Transaction) Delete(k key.Key) error { metrics.TxnCmdCounter.WithLabelValues("delete").Inc() return txn.us.Delete(k) } +// SetOption sets an option with a value, when val is nil, uses the default +// value of this option. func (txn *Transaction) SetOption(opt kv.Option, val interface{}) { txn.us.SetOption(opt, val) switch opt { @@ -160,6 +171,7 @@ func (txn *Transaction) SetOption(opt kv.Option, val interface{}) { } } +// DelOption deletes an option. func (txn *Transaction) DelOption(opt kv.Option) { txn.us.DelOption(opt) } @@ -168,6 +180,7 @@ func (txn *Transaction) close() { txn.valid = false } +// Commit commits the transaction operations to KV store. func (txn *Transaction) Commit(ctx context.Context) error { if !txn.valid { return kv.ErrInvalidTxn @@ -246,6 +259,7 @@ func (txn *Transaction) Commit(ctx context.Context) error { return err } +// Rollback undoes the transaction operations to KV store. func (txn *Transaction) Rollback() error { if !txn.valid { return kv.ErrInvalidTxn @@ -257,6 +271,7 @@ func (txn *Transaction) Rollback() error { return nil } +// LockKeys tries to lock the entries with the keys in KV store. func (txn *Transaction) LockKeys(keys ...key.Key) error { metrics.TxnCmdCounter.WithLabelValues("lock_keys").Inc() for _, key := range keys { @@ -265,14 +280,18 @@ func (txn *Transaction) LockKeys(keys ...key.Key) error { return nil } +// Valid returns if the transaction is valid. +// A transaction becomes invalid after commit or rollback. func (txn *Transaction) Valid() bool { return txn.valid } +// Len returns the count of key-value pairs in the transaction's memory buffer. func (txn *Transaction) Len() int { return txn.us.Len() } +// Size returns the length (in bytes) of the transaction's memory buffer. func (txn *Transaction) Size() int { return txn.us.Size() }