redis.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package cache
  2. import (
  3. "context"
  4. "errors"
  5. "time"
  6. "github.com/go-redis/redis/v8"
  7. )
  8. var (
  9. ctx = context.Background()
  10. defaultRedis *RedisCache
  11. )
  12. // RedisOptions options
  13. type RedisOptions struct {
  14. DB int
  15. PoolSize int
  16. DialTimeout time.Duration
  17. ReadTimeout time.Duration
  18. WriteTimeout time.Duration
  19. PoolTimeout time.Duration
  20. Password string
  21. Addr string
  22. }
  23. // RedisClusterOptions cluster option
  24. type RedisClusterOptions struct {
  25. DB int
  26. PoolSize int
  27. MaxRetries int
  28. MinRetryBackoff time.Duration
  29. MaxRetryBackoff time.Duration
  30. DialTimeout time.Duration
  31. ReadTimeout time.Duration
  32. WriteTimeout time.Duration
  33. PoolTimeout time.Duration
  34. IdleTimeout time.Duration
  35. IdleCheckFrequency time.Duration
  36. Password string
  37. Addrs []string
  38. }
  39. // RedisCache define
  40. type RedisCache struct {
  41. cluster bool
  42. ps *redis.PubSub
  43. c *redis.Client
  44. cc *redis.ClusterClient
  45. }
  46. // NewRedisCache new RedisCache object
  47. func NewRedisCache(opt RedisOptions) (rc *RedisCache, err error) {
  48. rc = new(RedisCache)
  49. c := redis.NewClient(&redis.Options{
  50. Addr: opt.Addr,
  51. Password: opt.Password,
  52. DialTimeout: opt.DialTimeout,
  53. ReadTimeout: opt.ReadTimeout,
  54. WriteTimeout: opt.WriteTimeout,
  55. PoolSize: opt.PoolSize,
  56. PoolTimeout: opt.PoolTimeout,
  57. })
  58. _, err = c.Ping(ctx).Result()
  59. rc.c = c
  60. rc.cluster = false
  61. return
  62. }
  63. // NewRedisClusterCache new RedisCluster object
  64. func NewRedisClusterCache(opt RedisClusterOptions) (rc *RedisCache, err error) {
  65. rc = new(RedisCache)
  66. var cfg redis.ClusterOptions
  67. cfg.Addrs = opt.Addrs
  68. cfg.Password = opt.Password
  69. cfg.DialTimeout = opt.DialTimeout
  70. cfg.ReadTimeout = opt.ReadTimeout
  71. cfg.WriteTimeout = opt.WriteTimeout
  72. cfg.PoolSize = opt.PoolSize
  73. cfg.PoolTimeout = opt.PoolTimeout
  74. cfg.IdleTimeout = opt.IdleTimeout
  75. cfg.IdleCheckFrequency = opt.IdleCheckFrequency
  76. c := redis.NewClusterClient(&cfg)
  77. _, err = c.Ping(ctx).Result()
  78. rc.cc = c
  79. rc.cluster = true
  80. return
  81. }
  82. // Reconnect reconnect
  83. func (c RedisCache) Reconnect() (s string, err error) {
  84. if c.cluster {
  85. s, err = c.cc.Ping(ctx).Result()
  86. return
  87. }
  88. s, err = c.c.Ping(ctx).Result()
  89. return
  90. }
  91. // Get get value from cache
  92. func (c RedisCache) Get(k string) (string, error) {
  93. if c.cluster {
  94. return c.cc.Get(ctx, k).Result()
  95. }
  96. return c.c.Get(ctx, k).Result()
  97. }
  98. // Set key-value to cache
  99. func (c RedisCache) Set(k, v string, expiration time.Duration) (string, error) {
  100. if c.cluster {
  101. return c.cc.Set(ctx, k, v, expiration).Result()
  102. }
  103. return c.c.Set(ctx, k, v, expiration).Result()
  104. }
  105. // Del delete key from cache
  106. func (c RedisCache) Del(ks ...string) (int64, error) {
  107. if c.cluster {
  108. return c.cc.Del(ctx, ks...).Result()
  109. }
  110. return c.c.Del(ctx, ks...).Result()
  111. }
  112. // Publish posts the message to the channel.
  113. func (c RedisCache) Publish(channel string, message interface{}) (int64, error) {
  114. if c.cluster {
  115. return c.cc.Publish(ctx, channel, message).Result()
  116. }
  117. return c.c.Publish(ctx, channel, message).Result()
  118. }
  119. // Subscribe subscribes the client to the specified channels.
  120. func (c *RedisCache) Subscribe(channels ...string) error {
  121. if c.cluster {
  122. c.ps = c.cc.Subscribe(ctx, channels...)
  123. } else {
  124. c.ps = c.c.Subscribe(ctx, channels...)
  125. }
  126. return c.ps.Ping(ctx)
  127. }
  128. // CloseSubscribe close
  129. func (c *RedisCache) CloseSubscribe() error {
  130. if c.ps == nil {
  131. return nil
  132. }
  133. return c.ps.Close()
  134. }
  135. // Unsubscribe the client from the given channels, or from all of them if none is given.
  136. func (c *RedisCache) Unsubscribe(channels ...string) error {
  137. if c.ps == nil {
  138. return nil
  139. }
  140. return c.ps.Unsubscribe(ctx, channels...)
  141. }
  142. // ReceiveSubscribeMessage returns a Message or error ignoring Subscription and Pong messages. This is low-level API and in most cases Channel should be used instead.
  143. func (c *RedisCache) ReceiveSubscribeMessage() (channel, message string, err error) {
  144. if c.ps == nil {
  145. err = errors.New("not init subscribe")
  146. return
  147. }
  148. var msg *redis.Message
  149. msg, err = c.ps.ReceiveMessage(ctx)
  150. if err != nil {
  151. return
  152. }
  153. channel = msg.Channel
  154. message = msg.Payload
  155. return
  156. }
  157. // Info redis info
  158. func (c RedisCache) Info(section ...string) (string, error) {
  159. if c.cluster {
  160. return c.cc.Info(ctx, section...).Result()
  161. }
  162. return c.c.Info(ctx, section...).Result()
  163. }
  164. // ClusterInfo redis cluster info
  165. func (c RedisCache) ClusterInfo() (string, error) {
  166. if c.cluster {
  167. return c.cc.ClusterInfo(ctx).Result()
  168. }
  169. return c.c.ClusterInfo(ctx).Result()
  170. }
  171. // SetDefaultRedisOption set default option
  172. func SetDefaultRedisOption(opt RedisOptions) (err error) {
  173. defaultRedis, err = NewRedisCache(opt)
  174. return
  175. }
  176. // SetDefaultRedisClusterOption set default cluster option
  177. func SetDefaultRedisClusterOption(opt RedisClusterOptions) (err error) {
  178. defaultRedis, err = NewRedisClusterCache(opt)
  179. return
  180. }
  181. // RedisReconnect re connect
  182. func RedisReconnect() (string, error) {
  183. return defaultRedis.Reconnect()
  184. }
  185. // RedisGet get value from cache
  186. func RedisGet(k string) (string, error) {
  187. return defaultRedis.Get(k)
  188. }
  189. // RedisSet key-value to cache
  190. func RedisSet(k, v string, expiration time.Duration) (string, error) {
  191. return defaultRedis.Set(k, v, expiration)
  192. }
  193. // RedisDel delete keys from cache
  194. func RedisDel(keys ...string) (int64, error) {
  195. return defaultRedis.Del(keys...)
  196. }
  197. // RedisInfo redis info
  198. func RedisInfo(section ...string) (string, error) {
  199. return defaultRedis.Info(section...)
  200. }
  201. // RedisClusterInfo redis cluster info
  202. func RedisClusterInfo() (string, error) {
  203. return defaultRedis.ClusterInfo()
  204. }
  205. // Publish posts the message to the channel.
  206. func RedisPublish(channel string, message interface{}) (int64, error) {
  207. return defaultRedis.Publish(channel, message)
  208. }
  209. // Subscribe subscribes the client to the specified channels.
  210. func RedisSubscribe(channels ...string) error {
  211. return defaultRedis.Subscribe(channels...)
  212. }
  213. // RedisCloseSubscribe close
  214. func RedisCloseSubscribe() error {
  215. return defaultRedis.CloseSubscribe()
  216. }
  217. // Unsubscribe the client from the given channels, or from all of them if none is given.
  218. func RedisUnsubscribe(channels ...string) error {
  219. return defaultRedis.Unsubscribe(channels...)
  220. }
  221. // RedisReceiveSubscribeMessage returns a Message or error ignoring Subscription and Pong messages. This is low-level API and in most cases Channel should be used instead.
  222. func RedisReceiveSubscribeMessage() (channel, message string, err error) {
  223. return defaultRedis.ReceiveSubscribeMessage()
  224. }