github.com/shuguocloud/go-zero@v1.3.0/core/stores/cache/cache.go (about)

     1  package cache
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/shuguocloud/go-zero/core/errorx"
     9  	"github.com/shuguocloud/go-zero/core/hash"
    10  	"github.com/shuguocloud/go-zero/core/syncx"
    11  )
    12  
    13  type (
    14  	// Cache interface is used to define the cache implementation.
    15  	Cache interface {
    16  		Del(keys ...string) error
    17  		Get(key string, v interface{}) error
    18  		IsNotFound(err error) bool
    19  		Set(key string, v interface{}) error
    20  		SetWithExpire(key string, v interface{}, expire time.Duration) error
    21  		Take(v interface{}, key string, query func(v interface{}) error) error
    22  		TakeWithExpire(v interface{}, key string, query func(v interface{}, expire time.Duration) error) error
    23  	}
    24  
    25  	cacheCluster struct {
    26  		dispatcher  *hash.ConsistentHash
    27  		errNotFound error
    28  	}
    29  )
    30  
    31  // New returns a Cache.
    32  func New(c ClusterConf, barrier syncx.SingleFlight, st *Stat, errNotFound error,
    33  	opts ...Option) Cache {
    34  	if len(c) == 0 || TotalWeights(c) <= 0 {
    35  		log.Fatal("no cache nodes")
    36  	}
    37  
    38  	if len(c) == 1 {
    39  		return NewNode(c[0].NewRedis(), barrier, st, errNotFound, opts...)
    40  	}
    41  
    42  	dispatcher := hash.NewConsistentHash()
    43  	for _, node := range c {
    44  		cn := NewNode(node.NewRedis(), barrier, st, errNotFound, opts...)
    45  		dispatcher.AddWithWeight(cn, node.Weight)
    46  	}
    47  
    48  	return cacheCluster{
    49  		dispatcher:  dispatcher,
    50  		errNotFound: errNotFound,
    51  	}
    52  }
    53  
    54  func (cc cacheCluster) Del(keys ...string) error {
    55  	switch len(keys) {
    56  	case 0:
    57  		return nil
    58  	case 1:
    59  		key := keys[0]
    60  		c, ok := cc.dispatcher.Get(key)
    61  		if !ok {
    62  			return cc.errNotFound
    63  		}
    64  
    65  		return c.(Cache).Del(key)
    66  	default:
    67  		var be errorx.BatchError
    68  		nodes := make(map[interface{}][]string)
    69  		for _, key := range keys {
    70  			c, ok := cc.dispatcher.Get(key)
    71  			if !ok {
    72  				be.Add(fmt.Errorf("key %q not found", key))
    73  				continue
    74  			}
    75  
    76  			nodes[c] = append(nodes[c], key)
    77  		}
    78  		for c, ks := range nodes {
    79  			if err := c.(Cache).Del(ks...); err != nil {
    80  				be.Add(err)
    81  			}
    82  		}
    83  
    84  		return be.Err()
    85  	}
    86  }
    87  
    88  func (cc cacheCluster) Get(key string, v interface{}) error {
    89  	c, ok := cc.dispatcher.Get(key)
    90  	if !ok {
    91  		return cc.errNotFound
    92  	}
    93  
    94  	return c.(Cache).Get(key, v)
    95  }
    96  
    97  func (cc cacheCluster) IsNotFound(err error) bool {
    98  	return err == cc.errNotFound
    99  }
   100  
   101  func (cc cacheCluster) Set(key string, v interface{}) error {
   102  	c, ok := cc.dispatcher.Get(key)
   103  	if !ok {
   104  		return cc.errNotFound
   105  	}
   106  
   107  	return c.(Cache).Set(key, v)
   108  }
   109  
   110  func (cc cacheCluster) SetWithExpire(key string, v interface{}, expire time.Duration) error {
   111  	c, ok := cc.dispatcher.Get(key)
   112  	if !ok {
   113  		return cc.errNotFound
   114  	}
   115  
   116  	return c.(Cache).SetWithExpire(key, v, expire)
   117  }
   118  
   119  func (cc cacheCluster) Take(v interface{}, key string, query func(v interface{}) error) error {
   120  	c, ok := cc.dispatcher.Get(key)
   121  	if !ok {
   122  		return cc.errNotFound
   123  	}
   124  
   125  	return c.(Cache).Take(v, key, query)
   126  }
   127  
   128  func (cc cacheCluster) TakeWithExpire(v interface{}, key string,
   129  	query func(v interface{}, expire time.Duration) error) error {
   130  	c, ok := cc.dispatcher.Get(key)
   131  	if !ok {
   132  		return cc.errNotFound
   133  	}
   134  
   135  	return c.(Cache).TakeWithExpire(v, key, query)
   136  }