diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 73b75733..1e9eb864 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,3 +1,12 @@ +# 1.0.0 (2022-01-05) + +- 删除 cachext 的 cacheNil 逻辑 + +**BREAKING CHANGE**: + +- 去掉 WithCacheNil 配置 +- 以前判断了 cachext.Nil 的地方,应该改为判断响应后 out 值是否为空值 + # 0.16.3 (2021-10-09) - 修正 `DialOptions` 拼写 diff --git a/extensions/cachext/cached.go b/extensions/cachext/cached.go index 0fa5ab6f..eb1fe845 100644 --- a/extensions/cachext/cached.go +++ b/extensions/cachext/cached.go @@ -13,16 +13,9 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -const Nil = cacheNil("cache result is nil") - -type cacheNil string - -func (e cacheNil) Error() string { return string(e) } - // CachedConfig save the param and config for a cached func type CachedConfig struct { cache *CacheExt - cacheNil bool ttl time.Duration version int64 funcName string @@ -72,46 +65,22 @@ func (c *CachedConfig) GetResult(ctx context.Context, out interface{}, strArgs [ // Increment hit counter. c.cache.hitCounter.With(labels).Inc() } - if c.cacheNil && decodeIsNil(data) { - // 无法直接把out设置为nil,这里通过返回特殊的错误来表示nil。调用方需要判断 - return Nil - } return decode(data, out) } res, err := c.getResult(ctx, strArgs, intArgs) if err != nil { return err } - // 函数返回值与cacheNil需要设置的值相同,报错 - if c.cacheNil && decodeIsNil(res) { - return errors.New("Your response is conflict with cacheNil value") - } - - status := [2]bool{res == nil, c.cacheNil} // 函数返回值与是否cacheNil状态判断 - cacheNilHited := [2]bool{true, true} // 函数返回值是nil,同时cacheNil。 - noNeedCacheNil := [2]bool{true, false} // 函数返回值是nil,不cacheNil。 - switch status { - case cacheNilHited: - // Set nil 会保存一个[]byte{192}的结构到backend中 - nilBytes, _ := encode(nil) - if err = c.cache.backend.Set(ctx, c.cache.transKey(cacheKey), nilBytes, c.ttl); err != nil { - return err - } - return Nil - case noNeedCacheNil: - return Nil - default: - // 函数返回值非空,把结果放入缓存。不管是否cacheNil - if encodedBytes, err := encode(res); err != nil { + // 把结果放入缓存 + if encodedBytes, err := encode(res); err != nil { + return err + } else { + err = c.cache.backend.Set(ctx, c.cache.transKey(cacheKey), encodedBytes, c.ttl) + if err != nil { return err - } else { - err = c.cache.backend.Set(ctx, c.cache.transKey(cacheKey), encodedBytes, c.ttl) - if err != nil { - return err - } - return decode(encodedBytes, out) } + return decode(encodedBytes, out) } } @@ -125,7 +94,6 @@ func (c *CacheExt) Cached(funcName string, f cachedFunc, options ...cacheOption) c.cachedFuncName[funcName] = void{} cacheFuncConf := &CachedConfig{ ttl: 24 * 2 * time.Hour, - cacheNil: false, version: 1, cache: c, getResult: f, @@ -160,15 +128,6 @@ func WithVersion(version int64) cacheOption { } } -// WithCacheNil set whether cacheNil to cacheFuncConfig, if cacheNil seted and function returns nil, GetResult will return Nil -// cacheNil stored in redis with []byte{192} 0xC0 -func WithCacheNil(cacheNil bool) cacheOption { - return func(config *CachedConfig) error { - config.cacheNil = cacheNil - return nil - } -} - // WithMakeCacheKey you can write your own makeCacheKey, use this func to change the default makeCacheKey. // first param means funcName, the second param means version, next params mean real function input param. func WithMakeCacheKey(f makeCacheKeyFunc) cacheOption { diff --git a/extensions/cachext/ext.go b/extensions/cachext/ext.go index 7a374abe..aa155b49 100644 --- a/extensions/cachext/ext.go +++ b/extensions/cachext/ext.go @@ -1,7 +1,6 @@ package cachext import ( - "bytes" "context" "errors" "fmt" @@ -248,14 +247,6 @@ func decode(data []byte, out interface{}) error { return msgpack.Unmarshal(data, out) } -func decodeIsNil(data interface{}) bool { - if byteData, ok := data.([]byte); ok { - err := msgpack.NewDecoder(bytes.NewReader(byteData)).DecodeNil() - return (err == nil) - } - return false -} - // Create a collector for total cache request counter func newCacheRequestCounter() *prometheus.CounterVec { return promauto.NewCounterVec( diff --git a/extensions/cachext/ext_test.go b/extensions/cachext/ext_test.go index 5eaf265a..f53f6f90 100644 --- a/extensions/cachext/ext_test.go +++ b/extensions/cachext/ext_test.go @@ -152,7 +152,7 @@ func TestCacheExt_Operation(t *testing.T) { mydata := myData{} mydata.Value1 = 100 mydata.Value2 = "thre si a verty conplex data {}{}" - mydata.Value3 = []node{node{"这是第一个node", []string{"id1", "id2", "id3"}}, node{"这是第二个node", []string{"id4", "id5", "id6"}}} + mydata.Value3 = []node{{"这是第一个node", []string{"id1", "id2", "id3"}}, {"这是第二个node", []string{"id4", "id5", "id6"}}} if err := cache.Set(context.Background(), "cache_key_2", mydata, 10*time.Second); err != nil { t.Log(err) t.Errorf("Cache Set Failed") @@ -392,45 +392,34 @@ func TestCacheExt_Cached_Common(t *testing.T) { // nil f_nil := func(_ context.Context, names []string, arg []int64) (interface{}, error) { call_times += 1 - return nil, nil + return func() (*string, error) { + return nil, nil + }() } - c_f_nil := cache.Cached("f_nil", f_nil, cachext.WithVersion(2), cachext.WithTTL(10*time.Second), cachext.WithCacheNil(false)) - nil_res := "" + c_f_nil := cache.Cached("f_nil", f_nil, cachext.WithVersion(2), cachext.WithTTL(10*time.Second)) + nil_res := "content" call_times = 0 for i := 0; i <= 3; i++ { err := c_f_nil.GetResult(context.Background(), &nil_res, []string{}, []int64{}) - if err != cachext.Nil { - t.Errorf("Not Cache Nil failed") + if err != nil || nil_res != "" { + t.Errorf(err.Error()) } } if call_times != 4 { t.Log(nil_res, call_times) } - cn_f_nil := cache.Cached("cn_f_nil", f_nil, cachext.WithVersion(5), cachext.WithTTL(10*time.Second), cachext.WithCacheNil(true)) + nil_res = "content" + cn_f_nil := cache.Cached("cn_f_nil", f_nil, cachext.WithVersion(5), cachext.WithTTL(10*time.Second)) call_times = 0 for i := 0; i <= 3; i++ { err := cn_f_nil.GetResult(context.Background(), &nil_res, []string{}, []int64{}) - if err != cachext.Nil { - t.Errorf("Cache Nil failed") + if err != nil || nil_res != "" { + t.Errorf(err.Error()) } } if call_times != 1 { t.Log(nil_res, call_times) } - // nil 测试函数返回值与cacheNil预设值冲突时,报错情况 - f_evil_nil := func(_ context.Context, names []string, arg []int64) (interface{}, error) { - return []byte{192}, nil - } - c_f_evil_nil := cache.Cached("f_evil_nil", f_evil_nil, cachext.WithTTL(10*time.Second), cachext.WithVersion(2), cachext.WithCacheNil(true)) - if err := c_f_evil_nil.GetResult(context.Background(), &nil_res, []string{}, []int64{}); err == nil { - t.Log(nil_res, err, call_times) - t.Errorf("Evil Cache Nil happened") - } - c_f_kind_nil := cache.Cached("c_f_kind_nil", f_evil_nil, cachext.WithTTL(10*time.Second), cachext.WithVersion(2)) - if err := c_f_kind_nil.GetResult(context.Background(), &nil_res, []string{}, []int64{}); err != nil { - t.Log(nil_res, err, call_times) - t.Errorf("Evil Cache Nil happened") - } } func TestCacheExt_Cached_Struct(t *testing.T) { @@ -463,7 +452,7 @@ func TestCacheExt_Cached_Struct(t *testing.T) { mydata.Value2 = "thre si a verty conplex data {}{}" some_str := "some str" mydata.Value4 = some_str - mydata.Value3 = []node{node{"这是第一个node", []string{"id1", "id2", "id3"}}, node{"这是第二个node", []string{"id4", "id5", "id6"}}} + mydata.Value3 = []node{{"这是第一个node", []string{"id1", "id2", "id3"}}, {"这是第二个node", []string{"id4", "id5", "id6"}}} return mydata, nil } cached_complex_ff := cache.Cached("complex_ff", complex_ff, cachext.WithTTL(10*time.Second))