From 30cd98b0f484c2bd0787e6d0f901486568b5fa25 Mon Sep 17 00:00:00 2001 From: doashenzzg Date: Thu, 7 Mar 2024 14:24:25 +0800 Subject: [PATCH 1/3] perf: error handling --- remote/goredisv8adapter.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/remote/goredisv8adapter.go b/remote/goredisv8adapter.go index bfd1218..fd833fa 100644 --- a/remote/goredisv8adapter.go +++ b/remote/goredisv8adapter.go @@ -6,8 +6,6 @@ import ( "time" "github.com/go-redis/redis/v8" - - "github.com/daoshenzzg/jetcache-go/logger" ) var _ Remote = (*GoRedisV8Adaptor)(nil) @@ -55,16 +53,13 @@ func (r *GoRedisV8Adaptor) MGet(ctx context.Context, keys ...string) (map[string cmder, err := pipeline.Exec(ctx) if err != nil && !errors.Is(err, r.Nil()) { - logger.Error("MGet:pipeline.Exec error(%v)", err) + return nil, err } for idx, cmd := range cmder { if strCmd, ok := cmd.(*redis.StringCmd); ok { key := keyIdxMap[idx] - val, err := strCmd.Result() - if err != nil && !errors.Is(err, r.Nil()) { - logger.Error("MGet#strCmd(%s) error(%v)", keyIdxMap[idx], err) - } else if len(val) > 0 { + if val, _ := strCmd.Result(); len(val) > 0 { ret[key] = val } } From 24f0d64e9d7647b5ff7571750f6053bc67e52d7b Mon Sep 17 00:00:00 2001 From: doashenzzg Date: Thu, 7 Mar 2024 14:24:50 +0800 Subject: [PATCH 2/3] perf: error handling --- cachegeneric.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cachegeneric.go b/cachegeneric.go index 29fa046..a901c9e 100644 --- a/cachegeneric.go +++ b/cachegeneric.go @@ -31,7 +31,6 @@ func (w *T[K, V]) MGet(ctx context.Context, key string, ids []K, fn func(context fnValues, err := fn(ctx, missIds) if err != nil { c.statsHandler.IncrQueryFail(err) - logger.Error("MGet#fn(%s) error(%v)", util.JoinAny(",", ids), err) } else { placeholderValues := make(map[string]any, len(ids)) cacheValues := make(map[string]any, len(ids)) @@ -40,7 +39,7 @@ func (w *T[K, V]) MGet(ctx context.Context, key string, ids []K, fn func(context cacheKey := util.JoinAny(":", key, rk) if b, err := c.Marshal(rv); err != nil { placeholderValues[cacheKey] = notFoundPlaceholder - logger.Error("MGet#w.Marshal(%v) error(%v)", rv, err) + logger.Warn("MGet#w.Marshal(%v) error(%v)", rv, err) } else { cacheValues[cacheKey] = b } @@ -69,12 +68,12 @@ func (w *T[K, V]) MGet(ctx context.Context, key string, ids []K, fn func(context if c.remote != nil { if len(placeholderValues) > 0 { if err = c.remote.MSet(ctx, placeholderValues, c.notFoundExpiry); err != nil { - logger.Error("MGet#MSet error(%v)", err) + logger.Warn("MGet#remote.MSet error(%v)", err) } } if len(cacheValues) > 0 { if err = c.remote.MSet(ctx, cacheValues, c.remoteExpiry); err != nil { - logger.Error("MGet#MSet error(%v)", err) + logger.Warn("MGet#remote.MSet error(%v)", err) } } } @@ -100,7 +99,7 @@ func (w *T[K, V]) mGetCache(ctx context.Context, key string, ids []K) (v map[K]V } var varT V if err := c.Unmarshal(b, &varT); err != nil { - logger.Error("mGetCache#c.Unmarshal(%s) error(%v)", cacheKey, err) + logger.Warn("mGetCache#c.Unmarshal(%s) error(%v)", cacheKey, err) } else { v[id] = varT } @@ -130,7 +129,7 @@ func (w *T[K, V]) mGetCache(ctx context.Context, key string, ids []K) (v map[K]V } var varT V if err = c.Unmarshal(b, &varT); err != nil { - logger.Error("mGetCache#c.Unmarshal(%s) error(%v)", mk, err) + logger.Warn("mGetCache#c.Unmarshal(%s) error(%v)", mk, err) } else { v[mv] = varT if c.local != nil { From 47cba5bd06ab8f571fc246ea139bce8e675c5baa Mon Sep 17 00:00:00 2001 From: doashenzzg Date: Thu, 7 Mar 2024 15:39:11 +0800 Subject: [PATCH 3/3] test: add unit test cases --- cache_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/cache_test.go b/cache_test.go index 8c2ddc6..3e5f9d4 100644 --- a/cache_test.go +++ b/cache_test.go @@ -312,6 +312,24 @@ var _ = Describe("Cache", func() { Expect(ret).To(Equal(map[int]*object{})) } }) + + It("with will skip elements that remote MSet error", func() { + if cache.CacheType() == TypeRemote { + codecErrCache := New(WithName("codecErr"), + WithRemote(&mockGoRedisMGetMSetErrAdapter{})) + cacheT := NewT[int, *object](codecErrCache) + ids := []int{1, 2, 3} + // 1st marshal error, but return origin load func data + ret := cacheT.MGet(context.Background(), "key", ids, + func(ctx context.Context, ids []int) (map[int]*object, error) { + return map[int]*object{1: {Str: "str1", Num: 1}, 2: {Str: "str2", Num: 2}}, nil + }) + Expect(ret).To(Equal(map[int]*object{1: {Str: "str1", Num: 1}, 2: {Str: "str2", Num: 2}})) + // 2nd cache hit placeholder "*", then return miss + ret = cacheT.MGet(context.Background(), "key", ids, nil) + Expect(ret).To(Equal(map[int]*object{})) + } + }) }) Describe("Once func", func() { @@ -738,3 +756,40 @@ func (mockEncode) Unmarshal(data []byte, v interface{}) error { func (mockEncode) Name() string { return mockMarshalErr } + +var _ remote.Remote = (*mockGoRedisMGetMSetErrAdapter)(nil) + +type mockGoRedisMGetMSetErrAdapter struct { +} + +func (m mockGoRedisMGetMSetErrAdapter) SetEX(ctx context.Context, key string, value any, expire time.Duration) error { + panic("implement me") +} + +func (m mockGoRedisMGetMSetErrAdapter) SetNX(ctx context.Context, key string, value any, expire time.Duration) (val bool, err error) { + panic("implement me") +} + +func (m mockGoRedisMGetMSetErrAdapter) SetXX(ctx context.Context, key string, value any, expire time.Duration) (val bool, err error) { + panic("implement me") +} + +func (m mockGoRedisMGetMSetErrAdapter) Get(ctx context.Context, key string) (val string, err error) { + panic("implement me") +} + +func (m mockGoRedisMGetMSetErrAdapter) Del(ctx context.Context, key string) (val int64, err error) { + panic("implement me") +} + +func (m mockGoRedisMGetMSetErrAdapter) MGet(ctx context.Context, keys ...string) (map[string]any, error) { + return nil, errors.New("any") +} + +func (m mockGoRedisMGetMSetErrAdapter) MSet(ctx context.Context, value map[string]any, expire time.Duration) error { + return errors.New("any") +} + +func (m mockGoRedisMGetMSetErrAdapter) Nil() error { + panic("implement me") +}