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  }