| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 | 
							- package redis
 
- import (
 
- 	"context"
 
- 	"fmt"
 
- 	"kpt-pasture/config"
 
- 	"math/rand"
 
- 	"time"
 
- 	"gitee.com/xuyiping_admin/pkg/xerr"
 
- 	"github.com/eko/gocache/cache"
 
- 	"github.com/eko/gocache/marshaler"
 
- 	"github.com/eko/gocache/metrics"
 
- 	"github.com/eko/gocache/store"
 
- 	redisv7 "github.com/go-redis/redis/v7"
 
- )
 
- func init() {
 
- 	rand.Seed(time.Now().UnixNano())
 
- }
 
- // Options redis 使用约束
 
- type Options = store.Options
 
- // TTL redis key TTL
 
- func TTL(duration time.Duration) *Options {
 
- 	return &store.Options{
 
- 		// 避免集中过期
 
- 		Expiration: duration + time.Duration(rand.Int31n(100))*time.Second,
 
- 	}
 
- }
 
- // CacheObject 缓存对象
 
- type CacheObject interface {
 
- 	CacheKey() string
 
- }
 
- // CacheStoreRedis Redis 缓存实例
 
- //
 
- //go:generate mockgen -destination mock/redismock.go -package redismock kpt_event/service/redis CacheStoreRedis
 
- type CacheStoreRedis interface {
 
- 	Namespace() string
 
- 	SetNamespace(string)
 
- 	// FullKey 返回带命名空间的完整key
 
- 	FullKey(key string) string
 
- 	Client() *redisv7.Client
 
- 	Get(ctx context.Context, Obj CacheObject) (interface{}, error)
 
- 	BatchGet(ctx context.Context, objects []CacheObject) (map[string]interface{}, error)
 
- 	Set(ctx context.Context, Obj CacheObject, options *store.Options) error
 
- 	TTL(ctx context.Context, obj CacheObject) (time.Duration, error)
 
- 	Delete(ctx context.Context, keys ...interface{}) error
 
- }
 
- func NewCacheStoreRedis(cfg *config.AppConfig) CacheStoreRedis {
 
- 	return NewCacheStoreRedisEntry(cfg)
 
- }
 
- func NewCacheStoreRedisEntry(cfg *config.AppConfig) *CacheStoreRedisEntry {
 
- 	client := NewClientLatest(cfg)
 
- 	redisStore := store.NewRedis(client, nil)
 
- 	promMetrics := metrics.NewPrometheus(cfg.Name())
 
- 	cacheManager := cache.NewMetric(promMetrics, cache.New(redisStore))
 
- 	marshal := marshaler.New(cacheManager)
 
- 	return &CacheStoreRedisEntry{
 
- 		client:         client,
 
- 		cacheNamespace: config.Options().CacheNameSpace(),
 
- 		cacheMarshal:   marshal,
 
- 	}
 
- }
 
- type CacheStoreRedisEntry struct {
 
- 	client         *redisv7.Client
 
- 	cacheNamespace string
 
- 	cacheMarshal   *marshaler.Marshaler
 
- }
 
- func (entry *CacheStoreRedisEntry) fullKey(key string) string {
 
- 	return fmt.Sprintf("%s:%s", entry.cacheNamespace, key)
 
- }
 
- func (entry *CacheStoreRedisEntry) FullKey(key string) string {
 
- 	return fmt.Sprintf("%s:%s", entry.cacheNamespace, key)
 
- }
 
- func (entry *CacheStoreRedisEntry) pureKey(key string) string {
 
- 	return key[len(entry.cacheNamespace):]
 
- }
 
- func (entry *CacheStoreRedisEntry) Namespace() string {
 
- 	return entry.cacheNamespace
 
- }
 
- func (entry *CacheStoreRedisEntry) SetNamespace(ns string) {
 
- 	entry.cacheNamespace = ns
 
- }
 
- func (entry *CacheStoreRedisEntry) Client() *redisv7.Client {
 
- 	return entry.client
 
- }
 
- func (entry *CacheStoreRedisEntry) BatchGet(ctx context.Context, objects []CacheObject) (map[string]interface{}, error) {
 
- 	result := make(map[string]interface{})
 
- 	for _, obj := range objects {
 
- 		got, err := entry.Get(ctx, obj)
 
- 		if err != nil {
 
- 			return nil, xerr.WithMessage(err, obj.CacheKey())
 
- 		}
 
- 		if got != nil {
 
- 			result[obj.CacheKey()] = got
 
- 		}
 
- 	}
 
- 	return result, nil
 
- }
 
- func (entry *CacheStoreRedisEntry) Get(ctx context.Context, obj CacheObject) (interface{}, error) {
 
- 	got, err := entry.cacheMarshal.Get(entry.fullKey(obj.CacheKey()), obj)
 
- 	if err != nil {
 
- 		if err == redisv7.Nil {
 
- 			return nil, nil
 
- 		}
 
- 		return nil, xerr.WithStack(err)
 
- 	}
 
- 	return got, nil
 
- }
 
- func (entry *CacheStoreRedisEntry) Set(ctx context.Context, obj CacheObject, options *store.Options) error {
 
- 	return entry.cacheMarshal.Set(entry.fullKey(obj.CacheKey()), obj, options)
 
- }
 
- func (entry *CacheStoreRedisEntry) TTL(ctx context.Context, obj CacheObject) (time.Duration, error) {
 
- 	return entry.client.TTL(entry.fullKey(obj.CacheKey())).Result()
 
- }
 
- func (entry *CacheStoreRedisEntry) Delete(ctx context.Context, keys ...interface{}) error {
 
- 	for _, key := range keys {
 
- 		switch keyItem := key.(type) {
 
- 		case string:
 
- 			if err := entry.cacheMarshal.Delete(entry.fullKey(keyItem)); err != nil {
 
- 				return xerr.WithStack(err)
 
- 			}
 
- 		case CacheObject:
 
- 			if err := entry.cacheMarshal.Delete(entry.fullKey(keyItem.CacheKey())); err != nil {
 
- 				return xerr.WithStack(err)
 
- 			}
 
- 		default:
 
- 			return xerr.New("invalid redis key type")
 
- 		}
 
- 	}
 
- 	return nil
 
- }
 
 
  |