123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- package cache
- import (
- "sync"
- "time"
- "github.com/go-redis/redis"
- )
- // RedisConfig config
- type RedisConfig struct {
- Addr string
- Password string
- DialTimeout time.Duration
- ReadTimeout time.Duration
- WriteTimeout time.Duration
- PoolTimeout time.Duration
- PoolSize int
- }
- // RedisClusterConfig redis cluster configure
- type RedisClusterConfig struct {
- // A seed list of host:port addresses of cluster nodes.
- Addrs []string
- // The maximum number of retries before giving up. Command is retried
- // on network errors and MOVED/ASK redirects.
- // Default is 16.
- MaxRedirects int
- // Enables read-only commands on slave nodes.
- ReadOnly bool
- // Allows routing read-only commands to the closest master or slave node.
- RouteByLatency bool
- //OnConnect func(*Conn) error
- MaxRetries int
- MinRetryBackoff time.Duration
- MaxRetryBackoff time.Duration
- Password string
- DialTimeout time.Duration
- ReadTimeout time.Duration
- WriteTimeout time.Duration
- // PoolSize applies per cluster node and not for the whole cluster.
- PoolSize int
- PoolTimeout time.Duration
- IdleTimeout time.Duration
- IdleCheckFrequency time.Duration
- }
- var (
- redisConfig RedisConfig
- redisClusterConfig RedisClusterConfig
- once sync.Once
- cache *RedisCache
- isCluster bool
- )
- // RedisCache define
- type RedisCache struct {
- c *redis.Client
- cc *redis.ClusterClient
- }
- // SetRedisConfig set
- func SetRedisConfig(cfg RedisConfig) {
- redisConfig = cfg
- }
- // SetRedisClusterConfig set
- func SetRedisClusterConfig(cfg RedisClusterConfig) {
- redisClusterConfig = cfg
- }
- // NewRedisCache new RedisCache object
- func NewRedisCache() *RedisCache {
- client := redis.NewClient(&redis.Options{
- Addr: redisConfig.Addr,
- Password: redisConfig.Password,
- DialTimeout: redisConfig.DialTimeout,
- ReadTimeout: redisConfig.ReadTimeout,
- WriteTimeout: redisConfig.WriteTimeout,
- PoolSize: redisConfig.PoolSize,
- PoolTimeout: redisConfig.PoolTimeout,
- })
- client.Ping().Result()
- return &RedisCache{c: client}
- }
- // NewRedisClusterCache new RedisCluster object
- func NewRedisClusterCache() *RedisCache {
- var config redis.ClusterOptions
- config.Addrs = redisClusterConfig.Addrs
- config.Password = redisClusterConfig.Password
- config.DialTimeout = redisClusterConfig.DialTimeout
- config.ReadTimeout = redisClusterConfig.ReadTimeout
- config.WriteTimeout = redisClusterConfig.WriteTimeout
- config.PoolSize = redisClusterConfig.PoolSize
- config.PoolTimeout = redisClusterConfig.PoolTimeout
- config.IdleTimeout = redisClusterConfig.IdleTimeout
- config.IdleCheckFrequency = redisClusterConfig.IdleCheckFrequency
- client := redis.NewClusterClient(&config)
- client.Ping()
- return &RedisCache{cc: client}
- }
- // Get get value from cache
- func (c RedisCache) Get(key string) (string, error) {
- if c.cc != nil {
- return c.cc.Get(key).Result()
- }
- return c.c.Get(key).Result()
- }
- // Set set key-value to cache
- func (c RedisCache) Set(key, value string, expiration time.Duration) error {
- if c.cc != nil {
- return c.cc.Set(key, value, expiration).Err()
- }
- return c.c.Set(key, value, expiration).Err()
- }
- // Del Del value from cache
- func (c RedisCache) Del(key string) (int64, error) {
- if c.cc != nil {
- return c.cc.Del(key).Result()
- }
- return c.c.Del(key).Result()
- }
- // Subscribe subscribe message
- func (c RedisCache) Subscribe(channels string, cb func(channel string, message string, err error)) {
- pubsub := &redis.PubSub{}
- if c.cc != nil {
- pubsub = c.cc.Subscribe(channels)
- } else {
- pubsub = c.c.Subscribe(channels)
- }
- defer pubsub.Close()
- var (
- msg *redis.Message
- err error
- )
- msg, err = pubsub.ReceiveMessage()
- for err == nil {
- cb(msg.Channel, msg.Payload, nil)
- msg, err = pubsub.ReceiveMessage()
- }
- cb("", "", err)
- return
- }
- // Publish publish message
- func (c RedisCache) Publish(channel, message string) error {
- return c.c.Publish(channel, message).Err()
- }
- // PublishCluster publish message
- func (c RedisCache) PublishCluster(channel, message string) error {
- return c.cc.Publish(channel, message).Err()
- }
- func connect() (*RedisCache, error) {
- if cache != nil {
- return cache, nil
- }
- //*
- var err error
- once.Do(func() {
- isCluster = false
- if len(redisConfig.Addr) > 0 {
- cache = NewRedisCache()
- }
- if len(redisClusterConfig.Addrs) > 0 {
- cache = NewRedisClusterCache()
- isCluster = true
- }
- })
- //*/
- return cache, err
- }
- // Get key from cache
- func Get(key string) (string, error) {
- c, err := connect()
- if err != nil {
- return "", err
- }
- return c.Get(key)
- }
- // Set key-value to cache
- func Set(key, value string, expiration time.Duration) error {
- c, err := connect()
- if err != nil {
- return err
- }
- return c.Set(key, value, expiration)
- }
- // Del delete key from cache
- func Del(key string) (int64, error) {
- c, err := connect()
- if err != nil {
- return 0, err
- }
- return c.Del(key)
- }
|