barometer: update DMA's vendoring packages
[barometer.git] / src / dma / vendor / github.com / go-redis / redis / options.go
1 package redis
2
3 import (
4         "crypto/tls"
5         "errors"
6         "fmt"
7         "net"
8         "net/url"
9         "runtime"
10         "strconv"
11         "strings"
12         "time"
13
14         "github.com/go-redis/redis/internal/pool"
15 )
16
17 // Limiter is the interface of a rate limiter or a circuit breaker.
18 type Limiter interface {
19         // Allow returns a nil if operation is allowed or an error otherwise.
20         // If operation is allowed client must report the result of operation
21         // whether is a success or a failure.
22         Allow() error
23         // ReportResult reports the result of previously allowed operation.
24         // nil indicates a success, non-nil error indicates a failure.
25         ReportResult(result error)
26 }
27
28 type Options struct {
29         // The network type, either tcp or unix.
30         // Default is tcp.
31         Network string
32         // host:port address.
33         Addr string
34
35         // Dialer creates new network connection and has priority over
36         // Network and Addr options.
37         Dialer func() (net.Conn, error)
38
39         // Hook that is called when new connection is established.
40         OnConnect func(*Conn) error
41
42         // Optional password. Must match the password specified in the
43         // requirepass server configuration option.
44         Password string
45         // Database to be selected after connecting to the server.
46         DB int
47
48         // Maximum number of retries before giving up.
49         // Default is to not retry failed commands.
50         MaxRetries int
51         // Minimum backoff between each retry.
52         // Default is 8 milliseconds; -1 disables backoff.
53         MinRetryBackoff time.Duration
54         // Maximum backoff between each retry.
55         // Default is 512 milliseconds; -1 disables backoff.
56         MaxRetryBackoff time.Duration
57
58         // Dial timeout for establishing new connections.
59         // Default is 5 seconds.
60         DialTimeout time.Duration
61         // Timeout for socket reads. If reached, commands will fail
62         // with a timeout instead of blocking. Use value -1 for no timeout and 0 for default.
63         // Default is 3 seconds.
64         ReadTimeout time.Duration
65         // Timeout for socket writes. If reached, commands will fail
66         // with a timeout instead of blocking.
67         // Default is ReadTimeout.
68         WriteTimeout time.Duration
69
70         // Maximum number of socket connections.
71         // Default is 10 connections per every CPU as reported by runtime.NumCPU.
72         PoolSize int
73         // Minimum number of idle connections which is useful when establishing
74         // new connection is slow.
75         MinIdleConns int
76         // Connection age at which client retires (closes) the connection.
77         // Default is to not close aged connections.
78         MaxConnAge time.Duration
79         // Amount of time client waits for connection if all connections
80         // are busy before returning an error.
81         // Default is ReadTimeout + 1 second.
82         PoolTimeout time.Duration
83         // Amount of time after which client closes idle connections.
84         // Should be less than server's timeout.
85         // Default is 5 minutes. -1 disables idle timeout check.
86         IdleTimeout time.Duration
87         // Frequency of idle checks made by idle connections reaper.
88         // Default is 1 minute. -1 disables idle connections reaper,
89         // but idle connections are still discarded by the client
90         // if IdleTimeout is set.
91         IdleCheckFrequency time.Duration
92
93         // Enables read only queries on slave nodes.
94         readOnly bool
95
96         // TLS Config to use. When set TLS will be negotiated.
97         TLSConfig *tls.Config
98 }
99
100 func (opt *Options) init() {
101         if opt.Network == "" {
102                 opt.Network = "tcp"
103         }
104         if opt.Addr == "" {
105                 opt.Addr = "localhost:6379"
106         }
107         if opt.Dialer == nil {
108                 opt.Dialer = func() (net.Conn, error) {
109                         netDialer := &net.Dialer{
110                                 Timeout:   opt.DialTimeout,
111                                 KeepAlive: 5 * time.Minute,
112                         }
113                         if opt.TLSConfig == nil {
114                                 return netDialer.Dial(opt.Network, opt.Addr)
115                         } else {
116                                 return tls.DialWithDialer(netDialer, opt.Network, opt.Addr, opt.TLSConfig)
117                         }
118                 }
119         }
120         if opt.PoolSize == 0 {
121                 opt.PoolSize = 10 * runtime.NumCPU()
122         }
123         if opt.DialTimeout == 0 {
124                 opt.DialTimeout = 5 * time.Second
125         }
126         switch opt.ReadTimeout {
127         case -1:
128                 opt.ReadTimeout = 0
129         case 0:
130                 opt.ReadTimeout = 3 * time.Second
131         }
132         switch opt.WriteTimeout {
133         case -1:
134                 opt.WriteTimeout = 0
135         case 0:
136                 opt.WriteTimeout = opt.ReadTimeout
137         }
138         if opt.PoolTimeout == 0 {
139                 opt.PoolTimeout = opt.ReadTimeout + time.Second
140         }
141         if opt.IdleTimeout == 0 {
142                 opt.IdleTimeout = 5 * time.Minute
143         }
144         if opt.IdleCheckFrequency == 0 {
145                 opt.IdleCheckFrequency = time.Minute
146         }
147
148         switch opt.MinRetryBackoff {
149         case -1:
150                 opt.MinRetryBackoff = 0
151         case 0:
152                 opt.MinRetryBackoff = 8 * time.Millisecond
153         }
154         switch opt.MaxRetryBackoff {
155         case -1:
156                 opt.MaxRetryBackoff = 0
157         case 0:
158                 opt.MaxRetryBackoff = 512 * time.Millisecond
159         }
160 }
161
162 // ParseURL parses an URL into Options that can be used to connect to Redis.
163 func ParseURL(redisURL string) (*Options, error) {
164         o := &Options{Network: "tcp"}
165         u, err := url.Parse(redisURL)
166         if err != nil {
167                 return nil, err
168         }
169
170         if u.Scheme != "redis" && u.Scheme != "rediss" {
171                 return nil, errors.New("invalid redis URL scheme: " + u.Scheme)
172         }
173
174         if u.User != nil {
175                 if p, ok := u.User.Password(); ok {
176                         o.Password = p
177                 }
178         }
179
180         if len(u.Query()) > 0 {
181                 return nil, errors.New("no options supported")
182         }
183
184         h, p, err := net.SplitHostPort(u.Host)
185         if err != nil {
186                 h = u.Host
187         }
188         if h == "" {
189                 h = "localhost"
190         }
191         if p == "" {
192                 p = "6379"
193         }
194         o.Addr = net.JoinHostPort(h, p)
195
196         f := strings.FieldsFunc(u.Path, func(r rune) bool {
197                 return r == '/'
198         })
199         switch len(f) {
200         case 0:
201                 o.DB = 0
202         case 1:
203                 if o.DB, err = strconv.Atoi(f[0]); err != nil {
204                         return nil, fmt.Errorf("invalid redis database number: %q", f[0])
205                 }
206         default:
207                 return nil, errors.New("invalid redis URL path: " + u.Path)
208         }
209
210         if u.Scheme == "rediss" {
211                 o.TLSConfig = &tls.Config{ServerName: h}
212         }
213         return o, nil
214 }
215
216 func newConnPool(opt *Options) *pool.ConnPool {
217         return pool.NewConnPool(&pool.Options{
218                 Dialer:             opt.Dialer,
219                 PoolSize:           opt.PoolSize,
220                 MinIdleConns:       opt.MinIdleConns,
221                 MaxConnAge:         opt.MaxConnAge,
222                 PoolTimeout:        opt.PoolTimeout,
223                 IdleTimeout:        opt.IdleTimeout,
224                 IdleCheckFrequency: opt.IdleCheckFrequency,
225         })
226 }