github.com/m3db/m3@v1.5.0/src/dbnode/client/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 client
    22  
    23  import (
    24  	"errors"
    25  	"math"
    26  	"runtime"
    27  	"time"
    28  
    29  	"github.com/uber/tchannel-go"
    30  	"github.com/uber/tchannel-go/thrift"
    31  
    32  	"github.com/m3db/m3/src/dbnode/encoding"
    33  	"github.com/m3db/m3/src/dbnode/encoding/m3tsz"
    34  	"github.com/m3db/m3/src/dbnode/encoding/proto"
    35  	"github.com/m3db/m3/src/dbnode/environment"
    36  	"github.com/m3db/m3/src/dbnode/generated/thrift/rpc"
    37  	"github.com/m3db/m3/src/dbnode/namespace"
    38  	nchannel "github.com/m3db/m3/src/dbnode/network/server/tchannelthrift/node/channel"
    39  	m3dbruntime "github.com/m3db/m3/src/dbnode/runtime"
    40  	"github.com/m3db/m3/src/dbnode/storage/index"
    41  	"github.com/m3db/m3/src/dbnode/topology"
    42  	"github.com/m3db/m3/src/dbnode/x/xio"
    43  	"github.com/m3db/m3/src/x/clock"
    44  	"github.com/m3db/m3/src/x/context"
    45  	"github.com/m3db/m3/src/x/ident"
    46  	"github.com/m3db/m3/src/x/instrument"
    47  	"github.com/m3db/m3/src/x/pool"
    48  	xretry "github.com/m3db/m3/src/x/retry"
    49  	"github.com/m3db/m3/src/x/sampler"
    50  	"github.com/m3db/m3/src/x/serialize"
    51  	xsync "github.com/m3db/m3/src/x/sync"
    52  )
    53  
    54  const (
    55  	// DefaultWriteBatchSize is the default write and write tagged batch size.
    56  	DefaultWriteBatchSize = 128
    57  
    58  	// defaultWriteConsistencyLevel is the default write consistency level
    59  	defaultWriteConsistencyLevel = m3dbruntime.DefaultWriteConsistencyLevel
    60  
    61  	// defaultReadConsistencyLevel is the default read consistency level
    62  	defaultReadConsistencyLevel = m3dbruntime.DefaultReadConsistencyLevel
    63  
    64  	// defaultBootstrapConsistencyLevel is the default bootstrap consistency level
    65  	defaultBootstrapConsistencyLevel = m3dbruntime.DefaultBootstrapConsistencyLevel
    66  
    67  	// defaultMaxConnectionCount is the default max connection count
    68  	defaultMaxConnectionCount = 32
    69  
    70  	// defaultMinConnectionCount is the default min connection count
    71  	defaultMinConnectionCount = 2
    72  
    73  	// defaultHostConnectTimeout is the default host connection timeout
    74  	defaultHostConnectTimeout = 5 * time.Second
    75  
    76  	// defaultClusterConnectTimeout is the default cluster connect timeout
    77  	defaultClusterConnectTimeout = 20 * time.Second
    78  
    79  	// defaultClusterConnectConsistencyLevel is the default cluster connect consistency level
    80  	defaultClusterConnectConsistencyLevel = topology.ConnectConsistencyLevelAny
    81  
    82  	// defaultWriteRequestTimeout is the default write request timeout
    83  	defaultWriteRequestTimeout = 10 * time.Second
    84  
    85  	// defaultFetchRequestTimeout is the default fetch request timeout
    86  	defaultFetchRequestTimeout = 15 * time.Second
    87  
    88  	// defaultTruncateRequestTimeout is the default truncate request timeout
    89  	defaultTruncateRequestTimeout = 60 * time.Second
    90  
    91  	// defaultWriteShardsInitializing is the default write to shards intializing value
    92  	defaultWriteShardsInitializing = true
    93  
    94  	// defaultShardsLeavingCountTowardsConsistency is the default shards leaving count towards consistency
    95  	defaultShardsLeavingCountTowardsConsistency = false
    96  
    97  	// defaultWriteOpPoolSize is the default write op pool size
    98  	defaultWriteOpPoolSize = 65536
    99  
   100  	// defaultWriteTaggedOpPoolSize is the default write tagged op pool size
   101  	defaultWriteTaggedOpPoolSize = 65536
   102  
   103  	// defaultFetchBatchOpPoolSize is the default fetch op pool size
   104  	defaultFetchBatchOpPoolSize = 1024
   105  
   106  	// defaultFetchBatchSize is the default fetch batch size
   107  	defaultFetchBatchSize = 128
   108  
   109  	// defaultCheckedBytesWrapperPoolSize is the default checkedBytesWrapperPoolSize
   110  	defaultCheckedBytesWrapperPoolSize = 65536
   111  
   112  	// defaultHostQueueOpsFlushSize is the default host queue ops flush size
   113  	defaultHostQueueOpsFlushSize = 128
   114  
   115  	// defaultHostQueueOpsFlushInterval is the default host queue flush interval
   116  	defaultHostQueueOpsFlushInterval = 5 * time.Millisecond
   117  
   118  	// defaultHostQueueOpsArrayPoolSize is the default host queue ops array pool size
   119  	defaultHostQueueOpsArrayPoolSize = 8
   120  
   121  	// defaultHostQueueEmitsHealthStatus is false
   122  	defaultHostQueueEmitsHealthStatus = true
   123  
   124  	// defaultBackgroundConnectInterval is the default background connect interval
   125  	defaultBackgroundConnectInterval = 4 * time.Second
   126  
   127  	// defaultBackgroundConnectStutter is the default background connect stutter
   128  	defaultBackgroundConnectStutter = 2 * time.Second
   129  
   130  	// defaultBackgroundHealthCheckInterval is the default background health check interval
   131  	defaultBackgroundHealthCheckInterval = 4 * time.Second
   132  
   133  	// defaultBackgroundHealthCheckStutter is the default background health check stutter
   134  	defaultBackgroundHealthCheckStutter = 2 * time.Second
   135  
   136  	// defaultBackgroundHealthCheckFailLimit is the default background health failure
   137  	// limit before connection is deemed unhealth
   138  	defaultBackgroundHealthCheckFailLimit = 4
   139  
   140  	// defaultBackgroundHealthCheckFailThrottleFactor is the default throttle factor to
   141  	// apply when calculating how long to wait between a failed health check and a
   142  	// retry attempt. It is applied by multiplying against the host connect
   143  	// timeout to produce a throttle sleep value.
   144  	defaultBackgroundHealthCheckFailThrottleFactor = 0.5
   145  
   146  	// defaultSeriesIteratorPoolSize is the default size of the series iterator pools
   147  	defaultSeriesIteratorPoolSize = 65536
   148  
   149  	// defaultTagEncoderPoolSize is the default size of the tag encoder pool.
   150  	defaultTagEncoderPoolSize = 4096
   151  
   152  	// defaultTagDecoderPoolSize is the default size of the tag decoder pool.
   153  	defaultTagDecoderPoolSize = 4096
   154  
   155  	// defaultFetchSeriesBlocksMaxBlockRetries is the default max retries for fetch series blocks
   156  	// from a single peer
   157  	defaultFetchSeriesBlocksMaxBlockRetries = 2
   158  
   159  	// defaultFetchSeriesBlocksBatchSize is the default fetch series blocks batch size
   160  	defaultFetchSeriesBlocksBatchSize = 4096
   161  
   162  	// defaultFetchSeriesBlocksMetadataBatchTimeout is the default series blocks metadata fetch timeout
   163  	defaultFetchSeriesBlocksMetadataBatchTimeout = 60 * time.Second
   164  
   165  	// defaultFetchSeriesBlocksMetadataBatchTimeout is the default series blocks contents fetch timeout
   166  	defaultFetchSeriesBlocksBatchTimeout = 60 * time.Second
   167  
   168  	// defaultAsyncWriteMaxConcurrency is the default maximum concurrency for async writes.
   169  	defaultAsyncWriteMaxConcurrency = 4096
   170  
   171  	// defaultUseV2BatchAPIs is the default setting for whether the v2 version of the batch APIs should
   172  	// be used.
   173  	defaultUseV2BatchAPIs = false
   174  
   175  	// defaultHostQueueWorkerPoolKillProbability is the default host queue worker pool
   176  	// kill probability.
   177  	defaultHostQueueWorkerPoolKillProbability = 0.01
   178  )
   179  
   180  var (
   181  	// defaultCheckedBytesPoolBucketSizes is the default bytes pool sizes
   182  	// used for both regular bytes pool as well as backs the identifier pool.
   183  	defaultCheckedBytesPoolBucketSizes = []pool.Bucket{
   184  		// Capacity 32 bucket mainly used for allocating for annotations.
   185  		{Capacity: 32, Count: 8192},
   186  		// Capacity 256 bucket mainly used for allocating IDs.
   187  		{Capacity: 256, Count: 8192},
   188  	}
   189  
   190  	// defaultFetchSeriesBlocksBatchConcurrency is the default fetch series blocks in batch parallel concurrency limit
   191  	defaultFetchSeriesBlocksBatchConcurrency = int(math.Max(1, float64(runtime.GOMAXPROCS(0))/2))
   192  
   193  	// defaultWriteRetrier is the default write retrier for write attempts
   194  	defaultWriteRetrier = xretry.NewRetrier(
   195  		xretry.NewOptions().
   196  			SetInitialBackoff(500 * time.Millisecond).
   197  			SetBackoffFactor(3).
   198  			SetMaxRetries(2).
   199  			SetJitter(true))
   200  
   201  	// defaultFetchRetrier is the default fetch retrier for fetch attempts
   202  	defaultFetchRetrier = xretry.NewRetrier(
   203  		xretry.NewOptions().
   204  			SetInitialBackoff(500 * time.Millisecond).
   205  			SetBackoffFactor(2).
   206  			SetMaxRetries(3).
   207  			SetJitter(true))
   208  
   209  	// defaultStreamBlocksRetrier is the default retrier for streaming blocks
   210  	defaultStreamBlocksRetrier = xretry.NewRetrier(
   211  		xretry.NewOptions().
   212  			SetBackoffFactor(2).
   213  			SetMaxRetries(3).
   214  			SetInitialBackoff(2 * time.Second).
   215  			SetJitter(true),
   216  	)
   217  
   218  	// defaultChannelOptions are default tchannel channel options.
   219  	defaultChannelOptions = &tchannel.ChannelOptions{
   220  		MaxIdleTime:       5 * time.Minute,
   221  		IdleCheckInterval: 5 * time.Minute,
   222  	}
   223  
   224  	// defaultThriftContextFn is the default thrift context function.
   225  	defaultThriftContextFn = thrift.Wrap
   226  
   227  	errNoTopologyInitializerSet    = errors.New("no topology initializer set")
   228  	errNoReaderIteratorAllocateSet = errors.New("no reader iterator allocator set, encoding not set")
   229  )
   230  
   231  type options struct {
   232  	runtimeOptsMgr                          m3dbruntime.OptionsManager
   233  	clockOpts                               clock.Options
   234  	instrumentOpts                          instrument.Options
   235  	logErrorSampleRate                      sampler.Rate
   236  	topologyInitializer                     topology.Initializer
   237  	readConsistencyLevel                    topology.ReadConsistencyLevel
   238  	writeConsistencyLevel                   topology.ConsistencyLevel
   239  	bootstrapConsistencyLevel               topology.ReadConsistencyLevel
   240  	channelOptions                          *tchannel.ChannelOptions
   241  	maxConnectionCount                      int
   242  	minConnectionCount                      int
   243  	hostConnectTimeout                      time.Duration
   244  	clusterConnectTimeout                   time.Duration
   245  	clusterConnectConsistencyLevel          topology.ConnectConsistencyLevel
   246  	writeRequestTimeout                     time.Duration
   247  	fetchRequestTimeout                     time.Duration
   248  	truncateRequestTimeout                  time.Duration
   249  	backgroundConnectInterval               time.Duration
   250  	backgroundConnectStutter                time.Duration
   251  	backgroundHealthCheckInterval           time.Duration
   252  	backgroundHealthCheckStutter            time.Duration
   253  	backgroundHealthCheckFailLimit          int
   254  	backgroundHealthCheckFailThrottleFactor float64
   255  	tagEncoderOpts                          serialize.TagEncoderOptions
   256  	tagEncoderPoolSize                      pool.Size
   257  	tagDecoderOpts                          serialize.TagDecoderOptions
   258  	tagDecoderPoolSize                      pool.Size
   259  	writeRetrier                            xretry.Retrier
   260  	fetchRetrier                            xretry.Retrier
   261  	streamBlocksRetrier                     xretry.Retrier
   262  	writeShardsInitializing                 bool
   263  	shardsLeavingCountTowardsConsistency    bool
   264  	newConnectionFn                         NewConnectionFn
   265  	readerIteratorAllocate                  encoding.ReaderIteratorAllocate
   266  	writeOperationPoolSize                  pool.Size
   267  	writeTaggedOperationPoolSize            pool.Size
   268  	fetchBatchOpPoolSize                    pool.Size
   269  	writeBatchSize                          int
   270  	fetchBatchSize                          int
   271  	checkedBytesPool                        pool.CheckedBytesPool
   272  	identifierPool                          ident.Pool
   273  	hostQueueOpsFlushSize                   int
   274  	hostQueueOpsFlushInterval               time.Duration
   275  	hostQueueOpsArrayPoolSize               pool.Size
   276  	hostQueueNewPooledWorkerFn              xsync.NewPooledWorkerFn
   277  	hostQueueEmitsHealthStatus              bool
   278  	seriesIteratorPoolSize                  pool.Size
   279  	checkedBytesWrapperPoolSize             pool.Size
   280  	contextPool                             context.Pool
   281  	origin                                  topology.Host
   282  	fetchSeriesBlocksMaxBlockRetries        int
   283  	fetchSeriesBlocksBatchSize              int
   284  	fetchSeriesBlocksMetadataBatchTimeout   time.Duration
   285  	fetchSeriesBlocksBatchTimeout           time.Duration
   286  	fetchSeriesBlocksBatchConcurrency       int
   287  	schemaRegistry                          namespace.SchemaRegistry
   288  	isProtoEnabled                          bool
   289  	asyncTopologyInitializers               []topology.Initializer
   290  	asyncWriteWorkerPool                    xsync.PooledWorkerPool
   291  	asyncWriteMaxConcurrency                int
   292  	useV2BatchAPIs                          bool
   293  	iterationOptions                        index.IterationOptions
   294  	writeTimestampOffset                    time.Duration
   295  	namespaceInitializer                    namespace.Initializer
   296  	thriftContextFn                         ThriftContextFn
   297  }
   298  
   299  // NewOptions creates a new set of client options with defaults
   300  func NewOptions() Options {
   301  	return newOptions()
   302  }
   303  
   304  // NewAdminOptions creates a new set of administration client options with defaults
   305  func NewAdminOptions() AdminOptions {
   306  	return newOptions()
   307  }
   308  
   309  // NewOptionsForAsyncClusters returns a slice of Options, where each is the set of client
   310  // for a given async client.
   311  func NewOptionsForAsyncClusters(opts Options, topoInits []topology.Initializer, overrides []environment.ClientOverrides) []Options {
   312  	result := make([]Options, 0, len(opts.AsyncTopologyInitializers()))
   313  	for i, topoInit := range topoInits {
   314  		options := opts.SetTopologyInitializer(topoInit)
   315  		if overrides[i].HostQueueFlushInterval != nil {
   316  			options = options.SetHostQueueOpsFlushInterval(*overrides[i].HostQueueFlushInterval)
   317  		}
   318  		if overrides[i].TargetHostQueueFlushSize != nil {
   319  			options = options.SetHostQueueOpsFlushSize(*overrides[i].TargetHostQueueFlushSize)
   320  		}
   321  		result = append(result, options)
   322  	}
   323  	return result
   324  }
   325  
   326  func defaultNewConnectionFn(
   327  	channelName string, address string, clientOpts Options,
   328  ) (Channel, rpc.TChanNode, error) {
   329  	// NB(r): Keep ref to a local channel options since it's actually modified
   330  	// by TChannel itself to set defaults.
   331  	var opts *tchannel.ChannelOptions
   332  	if chanOpts := clientOpts.ChannelOptions(); chanOpts != nil {
   333  		immutableOpts := *chanOpts
   334  		opts = &immutableOpts
   335  	}
   336  	channel, err := tchannel.NewChannel(channelName, opts)
   337  	if err != nil {
   338  		return nil, nil, err
   339  	}
   340  	endpoint := &thrift.ClientOptions{HostPort: address}
   341  	thriftClient := thrift.NewClient(channel, nchannel.ChannelName, endpoint)
   342  	client := rpc.NewTChanNodeClient(thriftClient)
   343  	return channel, client, nil
   344  }
   345  
   346  func newOptions() *options {
   347  	buckets := defaultCheckedBytesPoolBucketSizes
   348  	bytesPool := pool.NewCheckedBytesPool(buckets, nil,
   349  		func(sizes []pool.Bucket) pool.BytesPool {
   350  			return pool.NewBytesPool(sizes, nil)
   351  		})
   352  	bytesPool.Init()
   353  
   354  	idPoolSize := 0
   355  	for _, bucket := range buckets {
   356  		if v := int(bucket.Count); v > idPoolSize {
   357  			idPoolSize = v
   358  		}
   359  	}
   360  
   361  	poolOpts := pool.NewObjectPoolOptions().
   362  		SetSize(idPoolSize)
   363  
   364  	idPool := ident.NewPool(bytesPool, ident.PoolOptions{
   365  		IDPoolOptions:           poolOpts,
   366  		TagsPoolOptions:         poolOpts,
   367  		TagsIteratorPoolOptions: poolOpts,
   368  	})
   369  
   370  	contextPool := context.NewPool(context.NewOptions().
   371  		SetContextPoolOptions(poolOpts).
   372  		SetFinalizerPoolOptions(poolOpts))
   373  
   374  	hostQueueNewPooledWorkerFn := func(
   375  		opts xsync.NewPooledWorkerOptions,
   376  	) (xsync.PooledWorkerPool, error) {
   377  		if opts.InstrumentOptions == nil {
   378  			return nil, errors.New("instrument options required for new pooled worker fn")
   379  		}
   380  
   381  		workerPoolOpts := xsync.NewPooledWorkerPoolOptions().
   382  			SetGrowOnDemand(true).
   383  			SetKillWorkerProbability(defaultHostQueueWorkerPoolKillProbability).
   384  			SetInstrumentOptions(opts.InstrumentOptions)
   385  		return xsync.NewPooledWorkerPool(
   386  			int(workerPoolOpts.NumShards()),
   387  			workerPoolOpts)
   388  	}
   389  
   390  	opts := &options{
   391  		clockOpts:                               clock.NewOptions(),
   392  		instrumentOpts:                          instrument.NewOptions(),
   393  		channelOptions:                          defaultChannelOptions,
   394  		writeConsistencyLevel:                   defaultWriteConsistencyLevel,
   395  		readConsistencyLevel:                    defaultReadConsistencyLevel,
   396  		bootstrapConsistencyLevel:               defaultBootstrapConsistencyLevel,
   397  		maxConnectionCount:                      defaultMaxConnectionCount,
   398  		minConnectionCount:                      defaultMinConnectionCount,
   399  		hostConnectTimeout:                      defaultHostConnectTimeout,
   400  		clusterConnectTimeout:                   defaultClusterConnectTimeout,
   401  		clusterConnectConsistencyLevel:          defaultClusterConnectConsistencyLevel,
   402  		writeRequestTimeout:                     defaultWriteRequestTimeout,
   403  		fetchRequestTimeout:                     defaultFetchRequestTimeout,
   404  		truncateRequestTimeout:                  defaultTruncateRequestTimeout,
   405  		backgroundConnectInterval:               defaultBackgroundConnectInterval,
   406  		backgroundConnectStutter:                defaultBackgroundConnectStutter,
   407  		backgroundHealthCheckInterval:           defaultBackgroundHealthCheckInterval,
   408  		backgroundHealthCheckStutter:            defaultBackgroundHealthCheckStutter,
   409  		backgroundHealthCheckFailLimit:          defaultBackgroundHealthCheckFailLimit,
   410  		backgroundHealthCheckFailThrottleFactor: defaultBackgroundHealthCheckFailThrottleFactor,
   411  		writeRetrier:                            defaultWriteRetrier,
   412  		fetchRetrier:                            defaultFetchRetrier,
   413  		writeShardsInitializing:                 defaultWriteShardsInitializing,
   414  		shardsLeavingCountTowardsConsistency:    defaultShardsLeavingCountTowardsConsistency,
   415  		tagEncoderPoolSize:                      defaultTagEncoderPoolSize,
   416  		tagEncoderOpts:                          serialize.NewTagEncoderOptions(),
   417  		tagDecoderPoolSize:                      defaultTagDecoderPoolSize,
   418  		tagDecoderOpts:                          serialize.NewTagDecoderOptions(serialize.TagDecoderOptionsConfig{}),
   419  		streamBlocksRetrier:                     defaultStreamBlocksRetrier,
   420  		newConnectionFn:                         defaultNewConnectionFn,
   421  		writeOperationPoolSize:                  defaultWriteOpPoolSize,
   422  		writeTaggedOperationPoolSize:            defaultWriteTaggedOpPoolSize,
   423  		fetchBatchOpPoolSize:                    defaultFetchBatchOpPoolSize,
   424  		writeBatchSize:                          DefaultWriteBatchSize,
   425  		fetchBatchSize:                          defaultFetchBatchSize,
   426  		checkedBytesPool:                        bytesPool,
   427  		identifierPool:                          idPool,
   428  		hostQueueOpsFlushSize:                   defaultHostQueueOpsFlushSize,
   429  		hostQueueOpsFlushInterval:               defaultHostQueueOpsFlushInterval,
   430  		hostQueueOpsArrayPoolSize:               defaultHostQueueOpsArrayPoolSize,
   431  		hostQueueNewPooledWorkerFn:              hostQueueNewPooledWorkerFn,
   432  		hostQueueEmitsHealthStatus:              defaultHostQueueEmitsHealthStatus,
   433  		seriesIteratorPoolSize:                  defaultSeriesIteratorPoolSize,
   434  		checkedBytesWrapperPoolSize:             defaultCheckedBytesWrapperPoolSize,
   435  		contextPool:                             contextPool,
   436  		fetchSeriesBlocksMaxBlockRetries:        defaultFetchSeriesBlocksMaxBlockRetries,
   437  		fetchSeriesBlocksBatchSize:              defaultFetchSeriesBlocksBatchSize,
   438  		fetchSeriesBlocksMetadataBatchTimeout:   defaultFetchSeriesBlocksMetadataBatchTimeout,
   439  		fetchSeriesBlocksBatchTimeout:           defaultFetchSeriesBlocksBatchTimeout,
   440  		fetchSeriesBlocksBatchConcurrency:       defaultFetchSeriesBlocksBatchConcurrency,
   441  		schemaRegistry:                          namespace.NewSchemaRegistry(false, nil),
   442  		asyncTopologyInitializers:               []topology.Initializer{},
   443  		asyncWriteMaxConcurrency:                defaultAsyncWriteMaxConcurrency,
   444  		useV2BatchAPIs:                          defaultUseV2BatchAPIs,
   445  		thriftContextFn:                         defaultThriftContextFn,
   446  	}
   447  	return opts.SetEncodingM3TSZ().(*options)
   448  }
   449  
   450  func validate(opts *options) error {
   451  	if opts.topologyInitializer == nil {
   452  		return errNoTopologyInitializerSet
   453  	}
   454  	if opts.readerIteratorAllocate == nil {
   455  		return errNoReaderIteratorAllocateSet
   456  	}
   457  	if err := topology.ValidateConsistencyLevel(
   458  		opts.writeConsistencyLevel,
   459  	); err != nil {
   460  		return err
   461  	}
   462  	if err := topology.ValidateReadConsistencyLevel(
   463  		opts.readConsistencyLevel,
   464  	); err != nil {
   465  		return err
   466  	}
   467  	if err := topology.ValidateReadConsistencyLevel(
   468  		opts.bootstrapConsistencyLevel,
   469  	); err != nil {
   470  		return err
   471  	}
   472  	if err := topology.ValidateConnectConsistencyLevel(
   473  		opts.clusterConnectConsistencyLevel,
   474  	); err != nil {
   475  		return err
   476  	}
   477  	return opts.logErrorSampleRate.Validate()
   478  }
   479  
   480  func (o *options) Validate() error {
   481  	return validate(o)
   482  }
   483  
   484  func (o *options) SetEncodingM3TSZ() Options {
   485  	opts := *o
   486  	opts.readerIteratorAllocate = m3tsz.DefaultReaderIteratorAllocFn(encoding.NewOptions())
   487  	opts.isProtoEnabled = false
   488  	return &opts
   489  }
   490  
   491  func (o *options) SetEncodingProto(encodingOpts encoding.Options) Options {
   492  	opts := *o
   493  	opts.readerIteratorAllocate = func(
   494  		r xio.Reader64,
   495  		descr namespace.SchemaDescr,
   496  	) encoding.ReaderIterator {
   497  		return proto.NewIterator(r, descr, encodingOpts)
   498  	}
   499  	opts.isProtoEnabled = true
   500  	return &opts
   501  }
   502  
   503  func (o *options) IsSetEncodingProto() bool {
   504  	return o.isProtoEnabled
   505  }
   506  
   507  func (o *options) SetRuntimeOptionsManager(value m3dbruntime.OptionsManager) Options {
   508  	opts := *o
   509  	opts.runtimeOptsMgr = value
   510  	return &opts
   511  }
   512  
   513  func (o *options) RuntimeOptionsManager() m3dbruntime.OptionsManager {
   514  	return o.runtimeOptsMgr
   515  }
   516  
   517  func (o *options) SetClockOptions(value clock.Options) Options {
   518  	opts := *o
   519  	opts.clockOpts = value
   520  	return &opts
   521  }
   522  
   523  func (o *options) ClockOptions() clock.Options {
   524  	return o.clockOpts
   525  }
   526  
   527  func (o *options) SetInstrumentOptions(value instrument.Options) Options {
   528  	opts := *o
   529  	opts.instrumentOpts = value
   530  	return &opts
   531  }
   532  
   533  func (o *options) InstrumentOptions() instrument.Options {
   534  	return o.instrumentOpts
   535  }
   536  
   537  func (o *options) SetLogErrorSampleRate(value sampler.Rate) Options {
   538  	opts := *o
   539  	opts.logErrorSampleRate = value
   540  	return &opts
   541  }
   542  
   543  func (o *options) LogErrorSampleRate() sampler.Rate {
   544  	return o.logErrorSampleRate
   545  }
   546  
   547  func (o *options) SetTopologyInitializer(value topology.Initializer) Options {
   548  	opts := *o
   549  	opts.topologyInitializer = value
   550  	return &opts
   551  }
   552  
   553  func (o *options) TopologyInitializer() topology.Initializer {
   554  	return o.topologyInitializer
   555  }
   556  
   557  func (o *options) SetReadConsistencyLevel(value topology.ReadConsistencyLevel) Options {
   558  	opts := *o
   559  	opts.readConsistencyLevel = value
   560  	return &opts
   561  }
   562  
   563  func (o *options) ReadConsistencyLevel() topology.ReadConsistencyLevel {
   564  	return o.readConsistencyLevel
   565  }
   566  
   567  func (o *options) SetWriteConsistencyLevel(value topology.ConsistencyLevel) Options {
   568  	opts := *o
   569  	opts.writeConsistencyLevel = value
   570  	return &opts
   571  }
   572  
   573  func (o *options) WriteConsistencyLevel() topology.ConsistencyLevel {
   574  	return o.writeConsistencyLevel
   575  }
   576  
   577  func (o *options) SetBootstrapConsistencyLevel(value topology.ReadConsistencyLevel) AdminOptions {
   578  	opts := *o
   579  	opts.bootstrapConsistencyLevel = value
   580  	return &opts
   581  }
   582  
   583  func (o *options) BootstrapConsistencyLevel() topology.ReadConsistencyLevel {
   584  	return o.bootstrapConsistencyLevel
   585  }
   586  
   587  func (o *options) SetChannelOptions(value *tchannel.ChannelOptions) Options {
   588  	opts := *o
   589  	opts.channelOptions = value
   590  	return &opts
   591  }
   592  
   593  func (o *options) ChannelOptions() *tchannel.ChannelOptions {
   594  	return o.channelOptions
   595  }
   596  
   597  func (o *options) SetMaxConnectionCount(value int) Options {
   598  	opts := *o
   599  	opts.maxConnectionCount = value
   600  	return &opts
   601  }
   602  
   603  func (o *options) MaxConnectionCount() int {
   604  	return o.maxConnectionCount
   605  }
   606  
   607  func (o *options) SetMinConnectionCount(value int) Options {
   608  	opts := *o
   609  	opts.minConnectionCount = value
   610  	return &opts
   611  }
   612  
   613  func (o *options) MinConnectionCount() int {
   614  	return o.minConnectionCount
   615  }
   616  
   617  func (o *options) SetHostConnectTimeout(value time.Duration) Options {
   618  	opts := *o
   619  	opts.hostConnectTimeout = value
   620  	return &opts
   621  }
   622  
   623  func (o *options) HostConnectTimeout() time.Duration {
   624  	return o.hostConnectTimeout
   625  }
   626  
   627  func (o *options) SetClusterConnectTimeout(value time.Duration) Options {
   628  	opts := *o
   629  	opts.clusterConnectTimeout = value
   630  	return &opts
   631  }
   632  
   633  func (o *options) ClusterConnectTimeout() time.Duration {
   634  	return o.clusterConnectTimeout
   635  }
   636  
   637  func (o *options) SetClusterConnectConsistencyLevel(value topology.ConnectConsistencyLevel) Options {
   638  	opts := *o
   639  	opts.clusterConnectConsistencyLevel = value
   640  	return &opts
   641  }
   642  
   643  func (o *options) ClusterConnectConsistencyLevel() topology.ConnectConsistencyLevel {
   644  	return o.clusterConnectConsistencyLevel
   645  }
   646  
   647  func (o *options) SetWriteRequestTimeout(value time.Duration) Options {
   648  	opts := *o
   649  	opts.writeRequestTimeout = value
   650  	return &opts
   651  }
   652  
   653  func (o *options) WriteRequestTimeout() time.Duration {
   654  	return o.writeRequestTimeout
   655  }
   656  
   657  func (o *options) SetFetchRequestTimeout(value time.Duration) Options {
   658  	opts := *o
   659  	opts.fetchRequestTimeout = value
   660  	return &opts
   661  }
   662  
   663  func (o *options) FetchRequestTimeout() time.Duration {
   664  	return o.fetchRequestTimeout
   665  }
   666  
   667  func (o *options) SetTruncateRequestTimeout(value time.Duration) Options {
   668  	opts := *o
   669  	opts.truncateRequestTimeout = value
   670  	return &opts
   671  }
   672  
   673  func (o *options) TruncateRequestTimeout() time.Duration {
   674  	return o.truncateRequestTimeout
   675  }
   676  
   677  func (o *options) SetBackgroundConnectInterval(value time.Duration) Options {
   678  	opts := *o
   679  	opts.backgroundConnectInterval = value
   680  	return &opts
   681  }
   682  
   683  func (o *options) BackgroundConnectInterval() time.Duration {
   684  	return o.writeRequestTimeout
   685  }
   686  
   687  func (o *options) SetBackgroundConnectStutter(value time.Duration) Options {
   688  	opts := *o
   689  	opts.backgroundConnectStutter = value
   690  	return &opts
   691  }
   692  
   693  func (o *options) BackgroundConnectStutter() time.Duration {
   694  	return o.backgroundConnectStutter
   695  }
   696  
   697  func (o *options) SetBackgroundHealthCheckInterval(value time.Duration) Options {
   698  	opts := *o
   699  	opts.backgroundHealthCheckInterval = value
   700  	return &opts
   701  }
   702  
   703  func (o *options) BackgroundHealthCheckInterval() time.Duration {
   704  	return o.backgroundHealthCheckInterval
   705  }
   706  
   707  func (o *options) SetBackgroundHealthCheckStutter(value time.Duration) Options {
   708  	opts := *o
   709  	opts.backgroundHealthCheckStutter = value
   710  	return &opts
   711  }
   712  
   713  func (o *options) BackgroundHealthCheckStutter() time.Duration {
   714  	return o.backgroundHealthCheckStutter
   715  }
   716  
   717  func (o *options) SetBackgroundHealthCheckFailLimit(value int) Options {
   718  	opts := *o
   719  	opts.backgroundHealthCheckFailLimit = value
   720  	return &opts
   721  }
   722  
   723  func (o *options) BackgroundHealthCheckFailLimit() int {
   724  	return o.backgroundHealthCheckFailLimit
   725  }
   726  
   727  func (o *options) SetBackgroundHealthCheckFailThrottleFactor(value float64) Options {
   728  	opts := *o
   729  	opts.backgroundHealthCheckFailThrottleFactor = value
   730  	return &opts
   731  }
   732  
   733  func (o *options) BackgroundHealthCheckFailThrottleFactor() float64 {
   734  	return o.backgroundHealthCheckFailThrottleFactor
   735  }
   736  
   737  func (o *options) SetWriteRetrier(value xretry.Retrier) Options {
   738  	opts := *o
   739  	opts.writeRetrier = value
   740  	return &opts
   741  }
   742  
   743  func (o *options) WriteRetrier() xretry.Retrier {
   744  	return o.writeRetrier
   745  }
   746  
   747  func (o *options) SetFetchRetrier(value xretry.Retrier) Options {
   748  	opts := *o
   749  	opts.fetchRetrier = value
   750  	return &opts
   751  }
   752  
   753  func (o *options) FetchRetrier() xretry.Retrier {
   754  	return o.fetchRetrier
   755  }
   756  
   757  func (o *options) SetWriteShardsInitializing(value bool) Options {
   758  	opts := *o
   759  	opts.writeShardsInitializing = value
   760  	return &opts
   761  }
   762  
   763  func (o *options) WriteShardsInitializing() bool {
   764  	return o.writeShardsInitializing
   765  }
   766  
   767  func (o *options) SetShardsLeavingCountTowardsConsistency(value bool) Options {
   768  	opts := *o
   769  	opts.shardsLeavingCountTowardsConsistency = value
   770  	return &opts
   771  }
   772  
   773  func (o *options) ShardsLeavingCountTowardsConsistency() bool {
   774  	return o.shardsLeavingCountTowardsConsistency
   775  }
   776  
   777  func (o *options) SetTagEncoderOptions(value serialize.TagEncoderOptions) Options {
   778  	opts := *o
   779  	opts.tagEncoderOpts = value
   780  	return &opts
   781  }
   782  
   783  func (o *options) TagEncoderOptions() serialize.TagEncoderOptions {
   784  	return o.tagEncoderOpts
   785  }
   786  
   787  func (o *options) SetTagEncoderPoolSize(value pool.Size) Options {
   788  	opts := *o
   789  	opts.tagEncoderPoolSize = value
   790  	return &opts
   791  }
   792  
   793  func (o *options) TagEncoderPoolSize() pool.Size {
   794  	return o.tagEncoderPoolSize
   795  }
   796  
   797  func (o *options) SetTagDecoderOptions(value serialize.TagDecoderOptions) Options {
   798  	opts := *o
   799  	opts.tagDecoderOpts = value
   800  	return &opts
   801  }
   802  
   803  func (o *options) TagDecoderOptions() serialize.TagDecoderOptions {
   804  	return o.tagDecoderOpts
   805  }
   806  
   807  func (o *options) SetTagDecoderPoolSize(value pool.Size) Options {
   808  	opts := *o
   809  	opts.tagDecoderPoolSize = value
   810  	return &opts
   811  }
   812  
   813  func (o *options) TagDecoderPoolSize() pool.Size {
   814  	return o.tagDecoderPoolSize
   815  }
   816  
   817  func (o *options) SetStreamBlocksRetrier(value xretry.Retrier) AdminOptions {
   818  	opts := *o
   819  	opts.streamBlocksRetrier = value
   820  	return &opts
   821  }
   822  
   823  func (o *options) StreamBlocksRetrier() xretry.Retrier {
   824  	return o.streamBlocksRetrier
   825  }
   826  
   827  func (o *options) SetNewConnectionFn(value NewConnectionFn) AdminOptions {
   828  	opts := *o
   829  	opts.newConnectionFn = value
   830  	return &opts
   831  }
   832  
   833  func (o *options) NewConnectionFn() NewConnectionFn {
   834  	return o.newConnectionFn
   835  }
   836  
   837  func (o *options) SetWriteOpPoolSize(value pool.Size) Options {
   838  	opts := *o
   839  	opts.writeOperationPoolSize = value
   840  	return &opts
   841  }
   842  
   843  func (o *options) WriteOpPoolSize() pool.Size {
   844  	return o.writeOperationPoolSize
   845  }
   846  
   847  func (o *options) SetWriteTaggedOpPoolSize(value pool.Size) Options {
   848  	opts := *o
   849  	opts.writeTaggedOperationPoolSize = value
   850  	return &opts
   851  }
   852  
   853  func (o *options) WriteTaggedOpPoolSize() pool.Size {
   854  	return o.writeTaggedOperationPoolSize
   855  }
   856  
   857  func (o *options) SetFetchBatchOpPoolSize(value pool.Size) Options {
   858  	opts := *o
   859  	opts.fetchBatchOpPoolSize = value
   860  	return &opts
   861  }
   862  
   863  func (o *options) FetchBatchOpPoolSize() pool.Size {
   864  	return o.fetchBatchOpPoolSize
   865  }
   866  
   867  func (o *options) SetContextPool(value context.Pool) Options {
   868  	opts := *o
   869  	opts.contextPool = value
   870  	return &opts
   871  }
   872  
   873  func (o *options) ContextPool() context.Pool {
   874  	return o.contextPool
   875  }
   876  
   877  func (o *options) SetWriteBatchSize(value int) Options {
   878  	opts := *o
   879  	opts.writeBatchSize = value
   880  	return &opts
   881  }
   882  
   883  func (o *options) WriteBatchSize() int {
   884  	return o.writeBatchSize
   885  }
   886  
   887  func (o *options) SetFetchBatchSize(value int) Options {
   888  	opts := *o
   889  	opts.fetchBatchSize = value
   890  	return &opts
   891  }
   892  
   893  func (o *options) FetchBatchSize() int {
   894  	return o.fetchBatchSize
   895  }
   896  
   897  func (o *options) SetCheckedBytesPool(value pool.CheckedBytesPool) Options {
   898  	opts := *o
   899  	opts.checkedBytesPool = value
   900  	return &opts
   901  }
   902  
   903  func (o *options) CheckedBytesPool() pool.CheckedBytesPool {
   904  	return o.checkedBytesPool
   905  }
   906  
   907  func (o *options) SetIdentifierPool(value ident.Pool) Options {
   908  	opts := *o
   909  	opts.identifierPool = value
   910  	return &opts
   911  }
   912  
   913  func (o *options) IdentifierPool() ident.Pool {
   914  	return o.identifierPool
   915  }
   916  
   917  func (o *options) SetCheckedBytesWrapperPoolSize(value pool.Size) Options {
   918  	opts := *o
   919  	opts.checkedBytesWrapperPoolSize = value
   920  	return &opts
   921  }
   922  
   923  func (o *options) CheckedBytesWrapperPoolSize() pool.Size {
   924  	return o.checkedBytesWrapperPoolSize
   925  }
   926  
   927  func (o *options) SetHostQueueOpsFlushSize(value int) Options {
   928  	opts := *o
   929  	opts.hostQueueOpsFlushSize = value
   930  	return &opts
   931  }
   932  
   933  func (o *options) HostQueueOpsFlushSize() int {
   934  	return o.hostQueueOpsFlushSize
   935  }
   936  
   937  func (o *options) SetHostQueueOpsFlushInterval(value time.Duration) Options {
   938  	opts := *o
   939  	opts.hostQueueOpsFlushInterval = value
   940  	return &opts
   941  }
   942  
   943  func (o *options) HostQueueOpsFlushInterval() time.Duration {
   944  	return o.hostQueueOpsFlushInterval
   945  }
   946  
   947  func (o *options) SetHostQueueOpsArrayPoolSize(value pool.Size) Options {
   948  	opts := *o
   949  	opts.hostQueueOpsArrayPoolSize = value
   950  	return &opts
   951  }
   952  
   953  func (o *options) HostQueueOpsArrayPoolSize() pool.Size {
   954  	return o.hostQueueOpsArrayPoolSize
   955  }
   956  
   957  func (o *options) SetHostQueueNewPooledWorkerFn(value xsync.NewPooledWorkerFn) Options {
   958  	opts := *o
   959  	opts.hostQueueNewPooledWorkerFn = value
   960  	return &opts
   961  }
   962  
   963  func (o *options) HostQueueNewPooledWorkerFn() xsync.NewPooledWorkerFn {
   964  	return o.hostQueueNewPooledWorkerFn
   965  }
   966  
   967  func (o *options) SetHostQueueEmitsHealthStatus(value bool) Options {
   968  	opts := *o
   969  	opts.hostQueueEmitsHealthStatus = value
   970  	return &opts
   971  }
   972  
   973  func (o *options) HostQueueEmitsHealthStatus() bool {
   974  	return o.hostQueueEmitsHealthStatus
   975  }
   976  
   977  func (o *options) SetSeriesIteratorPoolSize(value pool.Size) Options {
   978  	opts := *o
   979  	opts.seriesIteratorPoolSize = value
   980  	return &opts
   981  }
   982  
   983  func (o *options) SeriesIteratorPoolSize() pool.Size {
   984  	return o.seriesIteratorPoolSize
   985  }
   986  
   987  func (o *options) SetReaderIteratorAllocate(value encoding.ReaderIteratorAllocate) Options {
   988  	opts := *o
   989  	opts.readerIteratorAllocate = value
   990  	return &opts
   991  }
   992  
   993  func (o *options) ReaderIteratorAllocate() encoding.ReaderIteratorAllocate {
   994  	return o.readerIteratorAllocate
   995  }
   996  
   997  func (o *options) SetSchemaRegistry(registry namespace.SchemaRegistry) AdminOptions {
   998  	opts := *o
   999  	opts.schemaRegistry = registry
  1000  	return &opts
  1001  }
  1002  
  1003  func (o *options) SchemaRegistry() namespace.SchemaRegistry {
  1004  	return o.schemaRegistry
  1005  }
  1006  
  1007  func (o *options) SetOrigin(value topology.Host) AdminOptions {
  1008  	opts := *o
  1009  	opts.origin = value
  1010  	return &opts
  1011  }
  1012  
  1013  func (o *options) Origin() topology.Host {
  1014  	return o.origin
  1015  }
  1016  
  1017  func (o *options) SetFetchSeriesBlocksMaxBlockRetries(value int) AdminOptions {
  1018  	opts := *o
  1019  	opts.fetchSeriesBlocksMaxBlockRetries = value
  1020  	return &opts
  1021  }
  1022  
  1023  func (o *options) FetchSeriesBlocksMaxBlockRetries() int {
  1024  	return o.fetchSeriesBlocksMaxBlockRetries
  1025  }
  1026  
  1027  func (o *options) SetFetchSeriesBlocksBatchSize(value int) AdminOptions {
  1028  	opts := *o
  1029  	opts.fetchSeriesBlocksBatchSize = value
  1030  	return &opts
  1031  }
  1032  
  1033  func (o *options) FetchSeriesBlocksBatchSize() int {
  1034  	return o.fetchSeriesBlocksBatchSize
  1035  }
  1036  
  1037  func (o *options) SetFetchSeriesBlocksMetadataBatchTimeout(value time.Duration) AdminOptions {
  1038  	opts := *o
  1039  	opts.fetchSeriesBlocksMetadataBatchTimeout = value
  1040  	return &opts
  1041  }
  1042  
  1043  func (o *options) FetchSeriesBlocksMetadataBatchTimeout() time.Duration {
  1044  	return o.fetchSeriesBlocksMetadataBatchTimeout
  1045  }
  1046  
  1047  func (o *options) SetFetchSeriesBlocksBatchTimeout(value time.Duration) AdminOptions {
  1048  	opts := *o
  1049  	opts.fetchSeriesBlocksBatchTimeout = value
  1050  	return &opts
  1051  }
  1052  
  1053  func (o *options) FetchSeriesBlocksBatchTimeout() time.Duration {
  1054  	return o.fetchSeriesBlocksBatchTimeout
  1055  }
  1056  
  1057  func (o *options) SetFetchSeriesBlocksBatchConcurrency(value int) AdminOptions {
  1058  	opts := *o
  1059  	opts.fetchSeriesBlocksBatchConcurrency = value
  1060  	return &opts
  1061  }
  1062  
  1063  func (o *options) FetchSeriesBlocksBatchConcurrency() int {
  1064  	return o.fetchSeriesBlocksBatchConcurrency
  1065  }
  1066  
  1067  func (o *options) SetAsyncTopologyInitializers(value []topology.Initializer) Options {
  1068  	opts := *o
  1069  	opts.asyncTopologyInitializers = value
  1070  	return &opts
  1071  }
  1072  
  1073  func (o *options) AsyncTopologyInitializers() []topology.Initializer {
  1074  	return o.asyncTopologyInitializers
  1075  }
  1076  
  1077  func (o *options) SetAsyncWriteWorkerPool(value xsync.PooledWorkerPool) Options {
  1078  	opts := *o
  1079  	opts.asyncWriteWorkerPool = value
  1080  	return &opts
  1081  }
  1082  
  1083  func (o *options) AsyncWriteWorkerPool() xsync.PooledWorkerPool {
  1084  	return o.asyncWriteWorkerPool
  1085  }
  1086  
  1087  func (o *options) SetAsyncWriteMaxConcurrency(value int) Options {
  1088  	opts := *o
  1089  	opts.asyncWriteMaxConcurrency = value
  1090  	return &opts
  1091  }
  1092  
  1093  func (o *options) AsyncWriteMaxConcurrency() int {
  1094  	return o.asyncWriteMaxConcurrency
  1095  }
  1096  
  1097  func (o *options) SetUseV2BatchAPIs(value bool) Options {
  1098  	opts := *o
  1099  	opts.useV2BatchAPIs = value
  1100  	return &opts
  1101  }
  1102  
  1103  func (o *options) UseV2BatchAPIs() bool {
  1104  	return o.useV2BatchAPIs
  1105  }
  1106  
  1107  func (o *options) SetIterationOptions(value index.IterationOptions) Options {
  1108  	opts := *o
  1109  	opts.iterationOptions = value
  1110  	return &opts
  1111  }
  1112  
  1113  func (o *options) IterationOptions() index.IterationOptions {
  1114  	return o.iterationOptions
  1115  }
  1116  
  1117  func (o *options) SetWriteTimestampOffset(value time.Duration) AdminOptions {
  1118  	opts := *o
  1119  	opts.writeTimestampOffset = value
  1120  	return &opts
  1121  }
  1122  
  1123  func (o *options) WriteTimestampOffset() time.Duration {
  1124  	return o.writeTimestampOffset
  1125  }
  1126  
  1127  func (o *options) SetNamespaceInitializer(value namespace.Initializer) Options {
  1128  	opts := *o
  1129  	opts.namespaceInitializer = value
  1130  	return &opts
  1131  }
  1132  
  1133  func (o *options) NamespaceInitializer() namespace.Initializer {
  1134  	return o.namespaceInitializer
  1135  }
  1136  
  1137  func (o *options) SetThriftContextFn(value ThriftContextFn) Options {
  1138  	opts := *o
  1139  	opts.thriftContextFn = value
  1140  	return &opts
  1141  }
  1142  
  1143  func (o *options) ThriftContextFn() ThriftContextFn {
  1144  	return o.thriftContextFn
  1145  }