github.com/wfusion/gofusion@v1.1.14/cache/redis.go (about) 1 package cache 2 3 import ( 4 "context" 5 "syscall" 6 "time" 7 8 "github.com/wfusion/gofusion/common/utils" 9 "github.com/wfusion/gofusion/config" 10 "github.com/wfusion/gofusion/log" 11 "github.com/wfusion/gofusion/redis" 12 13 rdsDrv "github.com/redis/go-redis/v9" 14 ) 15 16 type rds struct { 17 appName string 18 name string 19 log log.Loggable 20 instance rdsDrv.UniversalClient 21 } 22 23 func newRedis(appName, name string, log log.Loggable) provider { 24 return &rds{ 25 appName: appName, 26 name: name, 27 log: log, 28 instance: redis.Use(context.Background(), name, redis.AppName(appName)), 29 } 30 } 31 32 func (r *rds) get(ctx context.Context, keys ...string) (cached map[string]any, missed []string) { 33 cached = make(map[string]any, len(keys)) 34 missed = make([]string, 0, len(keys)) 35 36 rs, err := r.instance.MGet(ctx, keys...).Result() 37 if err != nil { 38 missed = keys 39 if r.log != nil { 40 r.log.Info(ctx, "%v [Gofusion] %s call redis mget failed when get cache from redis "+ 41 "[err[%s] redis[%s]]", syscall.Getpid(), config.ComponentCache, err, r.name) 42 } 43 return 44 } 45 for i := 0; i < len(keys); i++ { 46 if rs[i] != nil { 47 cached[keys[i]] = rs[i] 48 } else { 49 missed = append(missed, keys[i]) 50 } 51 } 52 53 return 54 } 55 56 func (r *rds) set(ctx context.Context, kvs map[string]any, expired map[string]time.Duration) (failure []string) { 57 failure = make([]string, 0, len(kvs)) 58 pipe := r.instance.Pipeline() 59 keys := make([]string, 0, len(kvs)) 60 for k, v := range kvs { 61 keys = append(keys, k) 62 pipe.Set(ctx, k, v, expired[k]) 63 } 64 65 cmds := utils.Must(pipe.Exec(ctx)) 66 for i := 0; i < len(keys); i++ { 67 if err := cmds[i].Err(); err != nil { 68 failure = append(failure, keys[i]) 69 if r.log != nil { 70 r.log.Info(ctx, "%v [Gofusion] %s call redis set failed when set cache into redis "+ 71 "[err[%s] redis[%s] key[%s]]", syscall.Getpid(), config.ComponentCache, err, r.name, keys[i]) 72 } 73 } 74 } 75 return 76 } 77 78 func (r *rds) del(ctx context.Context, keys ...string) (failure []string) { 79 affected, err := r.instance.Del(ctx, keys...).Result() 80 if err != nil && r.log != nil { 81 r.log.Info(ctx, "%v [Gofusion] %s call redis del failed when delete from cache "+ 82 "[err[%s] redis[%s] keys%v]", syscall.Getpid(), config.ComponentCache, err, r.name, keys) 83 } 84 85 if affected == int64(len(keys)) { 86 return 87 } 88 89 failure = make([]string, 0, len(keys)) 90 pipe := r.instance.Pipeline() 91 for i := 0; i < len(keys); i++ { 92 pipe.Exists(ctx, keys[i]) 93 } 94 cmds, err := pipe.Exec(ctx) 95 if err != nil && r.log != nil { 96 r.log.Info(ctx, "%v [Gofusion] %s call redis exists failed when delete from cache "+ 97 "[err[%s] redis[%s] keys%v]", syscall.Getpid(), config.ComponentCache, err, r.name, keys) 98 return keys // we cannot know whether ths keys are deleted 99 } 100 101 for i := 0; i < len(keys); i++ { 102 if err := cmds[i].Err(); err != nil { 103 failure = append(failure, keys[i]) // we cannot know whether ths key is deleted 104 r.log.Info(ctx, "%v [Gofusion] %s call redis exists failed when delete from cache "+ 105 "[err[%s] redis[%s] key[%s]]", syscall.Getpid(), config.ComponentCache, err, r.name, keys[i]) 106 continue 107 } 108 109 if cmds[i].String() == "1" { 110 failure = append(failure, keys[i]) 111 } 112 } 113 114 return 115 }