未验证 提交 a5c3f4ee 编写于 作者: C congqixia 提交者: GitHub

Add CompareFailErr for CAS operation error check (#15893)

Signed-off-by: NCongqi Xia <congqi.xia@zilliz.com>
上级 d199d00f
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"github.com/milvus-io/milvus/internal/kv" "github.com/milvus-io/milvus/internal/kv"
kvi "github.com/milvus-io/milvus/internal/kv"
"github.com/milvus-io/milvus/internal/log" "github.com/milvus-io/milvus/internal/log"
) )
...@@ -549,7 +550,7 @@ func (kv *EmbedEtcdKV) CompareValueAndSwap(key, value, target string, opts ...cl ...@@ -549,7 +550,7 @@ func (kv *EmbedEtcdKV) CompareValueAndSwap(key, value, target string, opts ...cl
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareValueAndSwap error for compare is false for key: %s", key) return kvi.NewCompareFailedError(fmt.Errorf("function CompareValueAndSwap error for compare is false for key: %s", key))
} }
return nil return nil
...@@ -570,7 +571,7 @@ func (kv *EmbedEtcdKV) CompareValueAndSwapBytes(key string, value, target []byte ...@@ -570,7 +571,7 @@ func (kv *EmbedEtcdKV) CompareValueAndSwapBytes(key string, value, target []byte
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareValueAndSwapBytes error for compare is false for key: %s", key) return kvi.NewCompareFailedError(fmt.Errorf("function CompareValueAndSwapBytes error for compare is false for key: %s", key))
} }
return nil return nil
...@@ -591,7 +592,7 @@ func (kv *EmbedEtcdKV) CompareVersionAndSwap(key string, version int64, target s ...@@ -591,7 +592,7 @@ func (kv *EmbedEtcdKV) CompareVersionAndSwap(key string, version int64, target s
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareAndSwap error for compare is false for key: %s", key) return kvi.NewCompareFailedError(fmt.Errorf("function CompareAndSwap error for compare is false for key: %s", key))
} }
return nil return nil
...@@ -612,7 +613,7 @@ func (kv *EmbedEtcdKV) CompareVersionAndSwapBytes(key string, version int64, tar ...@@ -612,7 +613,7 @@ func (kv *EmbedEtcdKV) CompareVersionAndSwapBytes(key string, version int64, tar
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareVersionAndSwapBytes error for compare is false for key: %s", key) return kvi.NewCompareFailedError(fmt.Errorf("function CompareVersionAndSwapBytes error for compare is false for key: %s", key))
} }
return nil return nil
......
...@@ -17,9 +17,11 @@ ...@@ -17,9 +17,11 @@
package etcdkv_test package etcdkv_test
import ( import (
"errors"
"os" "os"
"testing" "testing"
"github.com/milvus-io/milvus/internal/kv"
"github.com/milvus-io/milvus/internal/util/metricsinfo" "github.com/milvus-io/milvus/internal/util/metricsinfo"
embed_etcd_kv "github.com/milvus-io/milvus/internal/kv/etcd" embed_etcd_kv "github.com/milvus-io/milvus/internal/kv/etcd"
...@@ -800,6 +802,7 @@ func TestEmbedEtcd(te *testing.T) { ...@@ -800,6 +802,7 @@ func TestEmbedEtcd(te *testing.T) {
assert.Equal(t, revision+1, resp.Header.Revision) assert.Equal(t, revision+1, resp.Header.Revision)
} }
var compareErr *kv.CompareFailedError
err = metaKv.CompareVersionAndSwap("a/b/c", 0, "1") err = metaKv.CompareVersionAndSwap("a/b/c", 0, "1")
assert.NoError(t, err) assert.NoError(t, err)
...@@ -809,12 +812,14 @@ func TestEmbedEtcd(te *testing.T) { ...@@ -809,12 +812,14 @@ func TestEmbedEtcd(te *testing.T) {
err = metaKv.CompareVersionAndSwap("a/b/c", 0, "1") err = metaKv.CompareVersionAndSwap("a/b/c", 0, "1")
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
err = metaKv.CompareValueAndSwap("a/b/c", "1", "2") err = metaKv.CompareValueAndSwap("a/b/c", "1", "2")
assert.NoError(t, err) assert.NoError(t, err)
err = metaKv.CompareValueAndSwap("a/b/c", "1", "2") err = metaKv.CompareValueAndSwap("a/b/c", "1", "2")
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
}) })
te.Run("Etcd Revision Bytes", func(t *testing.T) { te.Run("Etcd Revision Bytes", func(t *testing.T) {
...@@ -852,6 +857,7 @@ func TestEmbedEtcd(te *testing.T) { ...@@ -852,6 +857,7 @@ func TestEmbedEtcd(te *testing.T) {
assert.Equal(t, revision+1, resp.Header.Revision) assert.Equal(t, revision+1, resp.Header.Revision)
} }
var compareErr *kv.CompareFailedError
err = metaKv.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1")) err = metaKv.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
assert.NoError(t, err) assert.NoError(t, err)
...@@ -861,12 +867,15 @@ func TestEmbedEtcd(te *testing.T) { ...@@ -861,12 +867,15 @@ func TestEmbedEtcd(te *testing.T) {
err = metaKv.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1")) err = metaKv.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
err = metaKv.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2")) err = metaKv.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
assert.NoError(t, err) assert.NoError(t, err)
err = metaKv.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2")) err = metaKv.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
}) })
te.Run("Etcd Lease", func(t *testing.T) { te.Run("Etcd Lease", func(t *testing.T) {
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"path" "path"
"time" "time"
kvi "github.com/milvus-io/milvus/internal/kv"
"github.com/milvus-io/milvus/internal/log" "github.com/milvus-io/milvus/internal/log"
clientv3 "go.etcd.io/etcd/client/v3" clientv3 "go.etcd.io/etcd/client/v3"
...@@ -567,7 +568,7 @@ func (kv *EtcdKV) CompareValueAndSwap(key, value, target string, opts ...clientv ...@@ -567,7 +568,7 @@ func (kv *EtcdKV) CompareValueAndSwap(key, value, target string, opts ...clientv
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareAndSwap error for compare is false for key: %s", key) return kvi.NewCompareFailedError(fmt.Errorf("function CompareAndSwap error for compare is false for key: %s", key))
} }
CheckElapseAndWarn(start, "Slow etcd operation compare value and swap") CheckElapseAndWarn(start, "Slow etcd operation compare value and swap")
return nil return nil
...@@ -589,7 +590,7 @@ func (kv *EtcdKV) CompareValueAndSwapBytes(key string, value, target []byte, opt ...@@ -589,7 +590,7 @@ func (kv *EtcdKV) CompareValueAndSwapBytes(key string, value, target []byte, opt
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareAndSwap error for compare is false for key: %s", key) return kvi.NewCompareFailedError(fmt.Errorf("function CompareAndSwap error for compare is false for key: %s", key))
} }
CheckElapseAndWarn(start, "Slow etcd operation compare value and swap") CheckElapseAndWarn(start, "Slow etcd operation compare value and swap")
return nil return nil
...@@ -611,8 +612,8 @@ func (kv *EtcdKV) CompareVersionAndSwap(key string, source int64, target string, ...@@ -611,8 +612,8 @@ func (kv *EtcdKV) CompareVersionAndSwap(key string, source int64, target string,
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareAndSwap error for compare is false for key: %s,"+ return kvi.NewCompareFailedError(fmt.Errorf("function CompareAndSwap error for compare is false for key: %s,"+
" source version: %d, target version: %s", key, source, target) " source version: %d, target version: %s", key, source, target))
} }
CheckElapseAndWarn(start, "Slow etcd operation compare version and swap") CheckElapseAndWarn(start, "Slow etcd operation compare version and swap")
return nil return nil
...@@ -634,8 +635,8 @@ func (kv *EtcdKV) CompareVersionAndSwapBytes(key string, source int64, target [] ...@@ -634,8 +635,8 @@ func (kv *EtcdKV) CompareVersionAndSwapBytes(key string, source int64, target []
return err return err
} }
if !resp.Succeeded { if !resp.Succeeded {
return fmt.Errorf("function CompareAndSwap error for compare is false for key: %s,"+ return kvi.NewCompareFailedError(fmt.Errorf("function CompareAndSwap error for compare is false for key: %s,"+
" source version: %d, target version: %s", key, source, target) " source version: %d, target version: %s", key, source, target))
} }
CheckElapseAndWarn(start, "Slow etcd operation compare version and swap") CheckElapseAndWarn(start, "Slow etcd operation compare version and swap")
return nil return nil
......
...@@ -17,10 +17,12 @@ ...@@ -17,10 +17,12 @@
package etcdkv_test package etcdkv_test
import ( import (
"errors"
"os" "os"
"testing" "testing"
"time" "time"
"github.com/milvus-io/milvus/internal/kv"
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd" etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
"github.com/milvus-io/milvus/internal/util/etcd" "github.com/milvus-io/milvus/internal/util/etcd"
"github.com/milvus-io/milvus/internal/util/paramtable" "github.com/milvus-io/milvus/internal/util/paramtable"
...@@ -723,6 +725,7 @@ func TestEtcdKV_Load(te *testing.T) { ...@@ -723,6 +725,7 @@ func TestEtcdKV_Load(te *testing.T) {
assert.Equal(t, revision+1, resp.Header.Revision) assert.Equal(t, revision+1, resp.Header.Revision)
} }
var compareErr *kv.CompareFailedError
err = etcdKV.CompareVersionAndSwap("a/b/c", 0, "1") err = etcdKV.CompareVersionAndSwap("a/b/c", 0, "1")
assert.NoError(t, err) assert.NoError(t, err)
...@@ -732,12 +735,14 @@ func TestEtcdKV_Load(te *testing.T) { ...@@ -732,12 +735,14 @@ func TestEtcdKV_Load(te *testing.T) {
err = etcdKV.CompareVersionAndSwap("a/b/c", 0, "1") err = etcdKV.CompareVersionAndSwap("a/b/c", 0, "1")
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
err = etcdKV.CompareValueAndSwap("a/b/c", "1", "2") err = etcdKV.CompareValueAndSwap("a/b/c", "1", "2")
assert.NoError(t, err) assert.NoError(t, err)
err = etcdKV.CompareValueAndSwap("a/b/c", "1", "2") err = etcdKV.CompareValueAndSwap("a/b/c", "1", "2")
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
}) })
te.Run("Etcd Revision Bytes", func(t *testing.T) { te.Run("Etcd Revision Bytes", func(t *testing.T) {
...@@ -772,6 +777,7 @@ func TestEtcdKV_Load(te *testing.T) { ...@@ -772,6 +777,7 @@ func TestEtcdKV_Load(te *testing.T) {
assert.Equal(t, revision+1, resp.Header.Revision) assert.Equal(t, revision+1, resp.Header.Revision)
} }
var compareErr *kv.CompareFailedError
err = etcdKV.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1")) err = etcdKV.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
assert.NoError(t, err) assert.NoError(t, err)
...@@ -781,12 +787,14 @@ func TestEtcdKV_Load(te *testing.T) { ...@@ -781,12 +787,14 @@ func TestEtcdKV_Load(te *testing.T) {
err = etcdKV.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1")) err = etcdKV.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
err = etcdKV.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2")) err = etcdKV.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
assert.NoError(t, err) assert.NoError(t, err)
err = etcdKV.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2")) err = etcdKV.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
assert.Error(t, err) assert.Error(t, err)
assert.True(t, errors.As(err, &compareErr))
}) })
te.Run("Etcd Lease", func(t *testing.T) { te.Run("Etcd Lease", func(t *testing.T) {
......
...@@ -21,6 +21,21 @@ import ( ...@@ -21,6 +21,21 @@ import (
clientv3 "go.etcd.io/etcd/client/v3" clientv3 "go.etcd.io/etcd/client/v3"
) )
// CompareFailedError is a helper type for checking MetaKv CompareAndSwap series func error type
type CompareFailedError struct {
internalError error
}
// Error implements error interface
func (e *CompareFailedError) Error() string {
return e.internalError.Error()
}
// NewCompareFailedError wraps error into NewCompareFailedError
func NewCompareFailedError(err error) error {
return &CompareFailedError{internalError: err}
}
// BaseKV contains base operations of kv. Include save, load and remove. // BaseKV contains base operations of kv. Include save, load and remove.
type BaseKV interface { type BaseKV interface {
Load(key string) (string, error) Load(key string) (string, error)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册