cache.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package cache
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/go-redis/redis"
  6. )
  7. type RedisConfig struct {
  8. Addrs []string
  9. Password string
  10. DB json.Number
  11. PoolSize json.Number
  12. MinIdleConns json.Number
  13. MaxRetries json.Number
  14. IsCluster string
  15. }
  16. type RedisCache struct {
  17. isCluster bool
  18. client *redis.Client
  19. cluster *redis.ClusterClient
  20. }
  21. func (p *RedisCache) Init(config RedisConfig) {
  22. if len(config.Addrs) == 0 {
  23. panic("Redis's addrs is empty.")
  24. }
  25. poolSize, _ := config.PoolSize.Int64()
  26. minIdleConns, _ := config.MinIdleConns.Int64()
  27. maxRetries, _ := config.MaxRetries.Int64()
  28. // redis is cluster?
  29. p.isCluster = (config.IsCluster == "true")
  30. if p.isCluster {
  31. p.cluster = redis.NewClusterClient(&redis.ClusterOptions{
  32. Addrs: config.Addrs,
  33. Password: config.Password,
  34. PoolSize: int(poolSize),
  35. MinIdleConns: int(minIdleConns),
  36. MaxRetries: int(maxRetries),
  37. })
  38. // check if redis server is ok.
  39. if _, err := p.cluster.Ping().Result(); err != nil {
  40. panic(err)
  41. }
  42. } else {
  43. db, _ := config.DB.Int64()
  44. p.client = redis.NewClient(&redis.Options{
  45. Addr: config.Addrs[0],
  46. Password: config.Password,
  47. DB: int(db),
  48. PoolSize: int(poolSize),
  49. MinIdleConns: int(minIdleConns),
  50. MaxRetries: int(maxRetries),
  51. })
  52. // check if redis server is ok.
  53. if _, err := p.client.Ping().Result(); err != nil {
  54. panic(err)
  55. }
  56. }
  57. }
  58. func (p *RedisCache) commandReturnStringSlice(args ...interface{}) (res []string, err error) {
  59. if p.isCluster {
  60. res, err = strings(p.cluster.Do(args...).Result())
  61. if err != nil {
  62. if res == nil || len(res) <= 0 {
  63. return nil, redis.Nil
  64. }
  65. }
  66. return
  67. }
  68. res, err = strings(p.client.Do(args...).Result())
  69. if err != nil {
  70. if res == nil || len(res) <= 0 {
  71. return nil, redis.Nil
  72. }
  73. }
  74. return
  75. }
  76. type Error string
  77. func (err Error) Error() string { return string(err) }
  78. func sliceHelper(reply interface{}, err error, name string, makeSlice func(int), assign func(int, interface{}) error) error {
  79. if err != nil {
  80. return err
  81. }
  82. switch reply := reply.(type) {
  83. case []interface{}:
  84. makeSlice(len(reply))
  85. for i := range reply {
  86. if reply[i] == nil {
  87. continue
  88. }
  89. if err := assign(i, reply[i]); err != nil {
  90. return err
  91. }
  92. }
  93. return nil
  94. case nil:
  95. return redis.Nil
  96. case Error:
  97. return reply
  98. }
  99. return fmt.Errorf("cache: unexpected type for %s, got type %T", name, reply)
  100. }
  101. func strings(reply interface{}, err error) ([]string, error) {
  102. var result []string
  103. err = sliceHelper(reply, err, "Strings", func(n int) { result = make([]string, n) }, func(i int, v interface{}) error {
  104. switch v := v.(type) {
  105. case string:
  106. result[i] = v
  107. return nil
  108. case []byte:
  109. result[i] = string(v)
  110. return nil
  111. default:
  112. return fmt.Errorf("cache: unexpected element type for Strings, got type %T", v)
  113. }
  114. })
  115. return result, err
  116. }