universal.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package redis
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "net"
  6. "time"
  7. )
  8. // UniversalOptions information is required by UniversalClient to establish
  9. // connections.
  10. type UniversalOptions struct {
  11. // Either a single address or a seed list of host:port addresses
  12. // of cluster/sentinel nodes.
  13. Addrs []string
  14. // Database to be selected after connecting to the server.
  15. // Only single-node and failover clients.
  16. DB int
  17. // Common options.
  18. Dialer func(ctx context.Context, network, addr string) (net.Conn, error)
  19. OnConnect func(*Conn) error
  20. Password string
  21. MaxRetries int
  22. MinRetryBackoff time.Duration
  23. MaxRetryBackoff time.Duration
  24. DialTimeout time.Duration
  25. ReadTimeout time.Duration
  26. WriteTimeout time.Duration
  27. PoolSize int
  28. MinIdleConns int
  29. MaxConnAge time.Duration
  30. PoolTimeout time.Duration
  31. IdleTimeout time.Duration
  32. IdleCheckFrequency time.Duration
  33. TLSConfig *tls.Config
  34. // Only cluster clients.
  35. MaxRedirects int
  36. ReadOnly bool
  37. RouteByLatency bool
  38. RouteRandomly bool
  39. // The sentinel master name.
  40. // Only failover clients.
  41. MasterName string
  42. }
  43. // Cluster returns cluster options created from the universal options.
  44. func (o *UniversalOptions) Cluster() *ClusterOptions {
  45. if len(o.Addrs) == 0 {
  46. o.Addrs = []string{"127.0.0.1:6379"}
  47. }
  48. return &ClusterOptions{
  49. Addrs: o.Addrs,
  50. Dialer: o.Dialer,
  51. OnConnect: o.OnConnect,
  52. Password: o.Password,
  53. MaxRedirects: o.MaxRedirects,
  54. ReadOnly: o.ReadOnly,
  55. RouteByLatency: o.RouteByLatency,
  56. RouteRandomly: o.RouteRandomly,
  57. MaxRetries: o.MaxRetries,
  58. MinRetryBackoff: o.MinRetryBackoff,
  59. MaxRetryBackoff: o.MaxRetryBackoff,
  60. DialTimeout: o.DialTimeout,
  61. ReadTimeout: o.ReadTimeout,
  62. WriteTimeout: o.WriteTimeout,
  63. PoolSize: o.PoolSize,
  64. MinIdleConns: o.MinIdleConns,
  65. MaxConnAge: o.MaxConnAge,
  66. PoolTimeout: o.PoolTimeout,
  67. IdleTimeout: o.IdleTimeout,
  68. IdleCheckFrequency: o.IdleCheckFrequency,
  69. TLSConfig: o.TLSConfig,
  70. }
  71. }
  72. // Failover returns failover options created from the universal options.
  73. func (o *UniversalOptions) Failover() *FailoverOptions {
  74. if len(o.Addrs) == 0 {
  75. o.Addrs = []string{"127.0.0.1:26379"}
  76. }
  77. return &FailoverOptions{
  78. SentinelAddrs: o.Addrs,
  79. MasterName: o.MasterName,
  80. Dialer: o.Dialer,
  81. OnConnect: o.OnConnect,
  82. DB: o.DB,
  83. Password: o.Password,
  84. MaxRetries: o.MaxRetries,
  85. MinRetryBackoff: o.MinRetryBackoff,
  86. MaxRetryBackoff: o.MaxRetryBackoff,
  87. DialTimeout: o.DialTimeout,
  88. ReadTimeout: o.ReadTimeout,
  89. WriteTimeout: o.WriteTimeout,
  90. PoolSize: o.PoolSize,
  91. MinIdleConns: o.MinIdleConns,
  92. MaxConnAge: o.MaxConnAge,
  93. PoolTimeout: o.PoolTimeout,
  94. IdleTimeout: o.IdleTimeout,
  95. IdleCheckFrequency: o.IdleCheckFrequency,
  96. TLSConfig: o.TLSConfig,
  97. }
  98. }
  99. // Simple returns basic options created from the universal options.
  100. func (o *UniversalOptions) Simple() *Options {
  101. addr := "127.0.0.1:6379"
  102. if len(o.Addrs) > 0 {
  103. addr = o.Addrs[0]
  104. }
  105. return &Options{
  106. Addr: addr,
  107. Dialer: o.Dialer,
  108. OnConnect: o.OnConnect,
  109. DB: o.DB,
  110. Password: o.Password,
  111. MaxRetries: o.MaxRetries,
  112. MinRetryBackoff: o.MinRetryBackoff,
  113. MaxRetryBackoff: o.MaxRetryBackoff,
  114. DialTimeout: o.DialTimeout,
  115. ReadTimeout: o.ReadTimeout,
  116. WriteTimeout: o.WriteTimeout,
  117. PoolSize: o.PoolSize,
  118. MinIdleConns: o.MinIdleConns,
  119. MaxConnAge: o.MaxConnAge,
  120. PoolTimeout: o.PoolTimeout,
  121. IdleTimeout: o.IdleTimeout,
  122. IdleCheckFrequency: o.IdleCheckFrequency,
  123. TLSConfig: o.TLSConfig,
  124. }
  125. }
  126. // --------------------------------------------------------------------
  127. // UniversalClient is an abstract client which - based on the provided options -
  128. // can connect to either clusters, or sentinel-backed failover instances
  129. // or simple single-instance servers. This can be useful for testing
  130. // cluster-specific applications locally.
  131. type UniversalClient interface {
  132. Cmdable
  133. Context() context.Context
  134. AddHook(Hook)
  135. Watch(fn func(*Tx) error, keys ...string) error
  136. Do(args ...interface{}) *Cmd
  137. DoContext(ctx context.Context, args ...interface{}) *Cmd
  138. Process(cmd Cmder) error
  139. ProcessContext(ctx context.Context, cmd Cmder) error
  140. Subscribe(channels ...string) *PubSub
  141. PSubscribe(channels ...string) *PubSub
  142. Close() error
  143. }
  144. var _ UniversalClient = (*Client)(nil)
  145. var _ UniversalClient = (*ClusterClient)(nil)
  146. var _ UniversalClient = (*Ring)(nil)
  147. // NewUniversalClient returns a new multi client. The type of client returned depends
  148. // on the following three conditions:
  149. //
  150. // 1. if a MasterName is passed a sentinel-backed FailoverClient will be returned
  151. // 2. if the number of Addrs is two or more, a ClusterClient will be returned
  152. // 3. otherwise, a single-node redis Client will be returned.
  153. func NewUniversalClient(opts *UniversalOptions) UniversalClient {
  154. if opts.MasterName != "" {
  155. return NewFailoverClient(opts.Failover())
  156. } else if len(opts.Addrs) > 1 {
  157. return NewClusterClient(opts.Cluster())
  158. }
  159. return NewClient(opts.Simple())
  160. }