package cache import ( "encoding/json" "fmt" "github.com/go-redis/redis" ) type RedisConfig struct { Addrs []string Password string DB json.Number PoolSize json.Number MinIdleConns json.Number MaxRetries json.Number IsCluster string } type RedisCache struct { isCluster bool client *redis.Client cluster *redis.ClusterClient } func (p *RedisCache) Init(config RedisConfig) { if len(config.Addrs) == 0 { panic("Redis's addrs is empty.") } poolSize, _ := config.PoolSize.Int64() minIdleConns, _ := config.MinIdleConns.Int64() maxRetries, _ := config.MaxRetries.Int64() // redis is cluster? p.isCluster = (config.IsCluster == "true") if p.isCluster { p.cluster = redis.NewClusterClient(&redis.ClusterOptions{ Addrs: config.Addrs, Password: config.Password, PoolSize: int(poolSize), MinIdleConns: int(minIdleConns), MaxRetries: int(maxRetries), }) // check if redis server is ok. if _, err := p.cluster.Ping().Result(); err != nil { panic(err) } } else { db, _ := config.DB.Int64() p.client = redis.NewClient(&redis.Options{ Addr: config.Addrs[0], Password: config.Password, DB: int(db), PoolSize: int(poolSize), MinIdleConns: int(minIdleConns), MaxRetries: int(maxRetries), }) // check if redis server is ok. if _, err := p.client.Ping().Result(); err != nil { panic(err) } } } func (p *RedisCache) commandReturnStringSlice(args ...interface{}) (res []string, err error) { if p.isCluster { res, err = strings(p.cluster.Do(args...).Result()) if err != nil { if res == nil || len(res) <= 0 { return nil, redis.Nil } } return } res, err = strings(p.client.Do(args...).Result()) if err != nil { if res == nil || len(res) <= 0 { return nil, redis.Nil } } return } type Error string func (err Error) Error() string { return string(err) } func sliceHelper(reply interface{}, err error, name string, makeSlice func(int), assign func(int, interface{}) error) error { if err != nil { return err } switch reply := reply.(type) { case []interface{}: makeSlice(len(reply)) for i := range reply { if reply[i] == nil { continue } if err := assign(i, reply[i]); err != nil { return err } } return nil case nil: return redis.Nil case Error: return reply } return fmt.Errorf("cache: unexpected type for %s, got type %T", name, reply) } func strings(reply interface{}, err error) ([]string, error) { var result []string err = sliceHelper(reply, err, "Strings", func(n int) { result = make([]string, n) }, func(i int, v interface{}) error { switch v := v.(type) { case string: result[i] = v return nil case []byte: result[i] = string(v) return nil default: return fmt.Errorf("cache: unexpected element type for Strings, got type %T", v) } }) return result, err }