github.com/m3db/m3@v1.5.0/src/cluster/kv/etcd/options.go (about) 1 // Copyright (c) 2016 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package etcd 22 23 import ( 24 "errors" 25 "fmt" 26 "os" 27 "time" 28 29 "github.com/m3db/m3/src/x/instrument" 30 "github.com/m3db/m3/src/x/retry" 31 ) 32 33 var ( 34 defaultRequestTimeout = 10 * time.Second 35 defaultWatchChanCheckInterval = 10 * time.Second 36 defaultWatchChanResetInterval = 10 * time.Second 37 defaultWatchChanInitTimeout = 10 * time.Second 38 defaultRetryOptions = retry.NewOptions().SetMaxRetries(5) 39 defaultCacheFileFn = func(string) string { return "" } 40 defaultNewDirectoryMode = os.FileMode(0755) 41 ) 42 43 // CacheFileFn is a function to generate cache file path 44 type CacheFileFn func(namespace string) string 45 46 // Options are options for the client of the kv store 47 type Options interface { 48 // RequestTimeout is the timeout for etcd requests 49 RequestTimeout() time.Duration 50 // SetRequestTimeout sets the RequestTimeout 51 SetRequestTimeout(t time.Duration) Options 52 53 // InstrumentsOptions is the instrument options 54 InstrumentsOptions() instrument.Options 55 // SetInstrumentsOptions sets the InstrumentsOptions 56 SetInstrumentsOptions(iopts instrument.Options) Options 57 58 // RetryOptions is the retry options 59 RetryOptions() retry.Options 60 // SetRetryOptions sets the RetryOptions 61 SetRetryOptions(ropts retry.Options) Options 62 63 // WatchChanCheckInterval will be used to periodically check if a watch chan 64 // is no longer being subscribed and should be closed 65 WatchChanCheckInterval() time.Duration 66 // SetWatchChanCheckInterval sets the WatchChanCheckInterval 67 SetWatchChanCheckInterval(t time.Duration) Options 68 69 // WatchChanResetInterval is the delay before resetting the etcd watch chan 70 WatchChanResetInterval() time.Duration 71 // SetWatchChanResetInterval sets the WatchChanResetInterval 72 SetWatchChanResetInterval(t time.Duration) Options 73 74 // WatchChanInitTimeout is the timeout for a watchChan initialization 75 WatchChanInitTimeout() time.Duration 76 // SetWatchChanInitTimeout sets the WatchChanInitTimeout 77 SetWatchChanInitTimeout(t time.Duration) Options 78 79 // WatchWithRevision is the revision that watch requests will start from. 80 WatchWithRevision() int64 81 82 // EnableFastGets returns whether to use clientv3.WithSerializable() option to speed up gets. 83 EnableFastGets() bool 84 // SetEnableFastGets sets clientv3.WithSerializable() to speed up gets, but can fetch stale data. 85 SetEnableFastGets(enabled bool) Options 86 87 // SetWatchWithRevision sets the revision that watch requests will start 88 // from. 89 SetWatchWithRevision(rev int64) Options 90 91 // Prefix is the prefix for each key 92 Prefix() string 93 // SetPrefix sets the prefix 94 SetPrefix(s string) Options 95 // ApplyPrefix applies the prefix to the key 96 ApplyPrefix(key string) string 97 98 // CacheFileDir is the dir for cache. 99 CacheFileFn() CacheFileFn 100 // SetCacheFileDir sets the CacheFileDir 101 SetCacheFileFn(fn CacheFileFn) Options 102 103 SetNewDirectoryMode(fm os.FileMode) Options 104 NewDirectoryMode() os.FileMode 105 106 // Validate validates the Options 107 Validate() error 108 } 109 110 type options struct { 111 requestTimeout time.Duration 112 prefix string 113 iopts instrument.Options 114 ropts retry.Options 115 watchChanCheckInterval time.Duration 116 watchChanResetInterval time.Duration 117 watchChanInitTimeout time.Duration 118 watchWithRevision int64 119 enableFastGets bool 120 cacheFileFn CacheFileFn 121 newDirectoryMode os.FileMode 122 } 123 124 // NewOptions creates a sane default Option 125 func NewOptions() Options { 126 o := options{} 127 return o.SetRequestTimeout(defaultRequestTimeout). 128 SetInstrumentsOptions(instrument.NewOptions()). 129 SetRetryOptions(defaultRetryOptions). 130 SetWatchChanCheckInterval(defaultWatchChanCheckInterval). 131 SetWatchChanResetInterval(defaultWatchChanResetInterval). 132 SetWatchChanInitTimeout(defaultWatchChanInitTimeout). 133 SetCacheFileFn(defaultCacheFileFn). 134 SetNewDirectoryMode(defaultNewDirectoryMode) 135 } 136 137 func (o options) Validate() error { 138 if o.iopts == nil { 139 return errors.New("no instrument options") 140 } 141 142 if o.ropts == nil { 143 return errors.New("no retry options") 144 } 145 146 if o.watchChanCheckInterval <= 0 { 147 return errors.New("invalid watch channel check interval") 148 } 149 150 if o.watchChanResetInterval <= 0 { 151 return errors.New("invalid watch reset interval") 152 } 153 154 if o.watchChanInitTimeout <= 0 { 155 return errors.New("invalid watch init interval") 156 } 157 158 if o.requestTimeout <= 0 { 159 return errors.New("invalid request timeout") 160 } 161 162 return nil 163 } 164 165 func (o options) RequestTimeout() time.Duration { 166 return o.requestTimeout 167 } 168 169 func (o options) SetRequestTimeout(t time.Duration) Options { 170 o.requestTimeout = t 171 return o 172 } 173 174 func (o options) InstrumentsOptions() instrument.Options { 175 return o.iopts 176 } 177 178 func (o options) SetInstrumentsOptions(iopts instrument.Options) Options { 179 o.iopts = iopts 180 return o 181 } 182 183 func (o options) RetryOptions() retry.Options { 184 return o.ropts 185 } 186 187 func (o options) SetRetryOptions(ropts retry.Options) Options { 188 o.ropts = ropts 189 return o 190 } 191 192 func (o options) WatchChanCheckInterval() time.Duration { 193 return o.watchChanCheckInterval 194 } 195 196 func (o options) SetWatchChanCheckInterval(t time.Duration) Options { 197 o.watchChanCheckInterval = t 198 return o 199 } 200 201 func (o options) WatchChanResetInterval() time.Duration { 202 return o.watchChanResetInterval 203 } 204 205 func (o options) SetWatchChanResetInterval(t time.Duration) Options { 206 o.watchChanResetInterval = t 207 return o 208 } 209 210 func (o options) WatchChanInitTimeout() time.Duration { 211 return o.watchChanInitTimeout 212 } 213 214 func (o options) SetWatchChanInitTimeout(t time.Duration) Options { 215 o.watchChanInitTimeout = t 216 return o 217 } 218 219 func (o options) WatchWithRevision() int64 { 220 return o.watchWithRevision 221 } 222 223 func (o options) SetWatchWithRevision(rev int64) Options { 224 o.watchWithRevision = rev 225 return o 226 } 227 228 //nolint:gocritic 229 func (o options) EnableFastGets() bool { 230 return o.enableFastGets 231 } 232 233 //nolint:gocritic 234 func (o options) SetEnableFastGets(enabled bool) Options { 235 o.enableFastGets = enabled 236 return o 237 } 238 239 func (o options) CacheFileFn() CacheFileFn { 240 return o.cacheFileFn 241 } 242 243 func (o options) SetCacheFileFn(fn CacheFileFn) Options { 244 o.cacheFileFn = fn 245 return o 246 } 247 248 func (o options) Prefix() string { 249 return o.prefix 250 } 251 252 func (o options) SetPrefix(prefix string) Options { 253 o.prefix = prefix 254 return o 255 } 256 257 func (o options) ApplyPrefix(key string) string { 258 if o.prefix == "" { 259 return key 260 } 261 return fmt.Sprintf("%s/%s", o.prefix, key) 262 } 263 264 func (o options) SetNewDirectoryMode(fm os.FileMode) Options { 265 o.newDirectoryMode = fm 266 return o 267 } 268 269 func (o options) NewDirectoryMode() os.FileMode { 270 return o.newDirectoryMode 271 }