github.com/m3db/m3@v1.5.0/src/msg/producer/writer/options.go (about)

     1  // Copyright (c) 2018 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 writer
    22  
    23  import (
    24  	"context"
    25  	"net"
    26  	"time"
    27  
    28  	"github.com/m3db/m3/src/cluster/placement"
    29  	"github.com/m3db/m3/src/cluster/services"
    30  	"github.com/m3db/m3/src/msg/protocol/proto"
    31  	"github.com/m3db/m3/src/msg/topic"
    32  	"github.com/m3db/m3/src/x/instrument"
    33  	"github.com/m3db/m3/src/x/pool"
    34  	"github.com/m3db/m3/src/x/retry"
    35  )
    36  
    37  const (
    38  	defaultPlacementWatchInitTimeout         = 2 * time.Second
    39  	defaultTopicWatchInitTimeout             = 2 * time.Second
    40  	defaultCloseCheckInterval                = time.Second
    41  	defaultMessageQueueNewWritesScanInterval = 200 * time.Millisecond
    42  	defaultMessageQueueFullScanInterval      = 5 * time.Second
    43  	defaultMessageQueueScanBatchSize         = 16
    44  	defaultInitialAckMapSize                 = 1024
    45  
    46  	defaultNumConnections            = 4
    47  	defaultConnectionDialTimeout     = 5 * time.Second
    48  	defaultConnectionWriteTimeout    = 5 * time.Second
    49  	defaultConnectionKeepAlivePeriod = 5 * time.Second
    50  	defaultConnectionResetDelay      = 2 * time.Second
    51  	defaultConnectionFlushInterval   = time.Second
    52  	// Using 65k which provides much better performance comparing
    53  	// to lower values like 1k ~ 8k.
    54  	defaultConnectionBufferSize = 2 << 15 // ~65kb
    55  
    56  	defaultWriterRetryInitialBackoff = time.Second * 5
    57  )
    58  
    59  // ContextDialerFn allows customization of how a m3msg Writer connects to producer endpoints.
    60  // See ConnectionOptions#ContextDialer
    61  type ContextDialerFn func(ctx context.Context, network string, address string) (net.Conn, error)
    62  
    63  // ConnectionOptions configs the connections.
    64  type ConnectionOptions interface {
    65  	// NumConnections returns the number of connections.
    66  	NumConnections() int
    67  
    68  	// SetNumConnections sets the number of connections.
    69  	SetNumConnections(value int) ConnectionOptions
    70  
    71  	// ContextDialer allows customizing the way a m3msg Writer connects to producer endpoints. By default, this is:
    72  	// (&net.ContextDialer{}).DialContext. This can be used to do a variety of things, such as forwarding a connection
    73  	// over a proxy.
    74  	// NOTE: if your ContextDialerFn returns anything other a *net.TCPConn, TCP options such as KeepAlivePeriod
    75  	// will *not* be applied automatically. It is your responsibility to make sure these get applied as needed in
    76  	// your custom ContextDialerFn.
    77  	ContextDialer() ContextDialerFn
    78  
    79  	// SetContextDialer see ContextDialer.
    80  	SetContextDialer(fn ContextDialerFn) ConnectionOptions
    81  
    82  	// DialTimeout returns the dial timeout.
    83  	DialTimeout() time.Duration
    84  
    85  	// SetDialTimeout sets the dial timeout.
    86  	SetDialTimeout(value time.Duration) ConnectionOptions
    87  
    88  	// WriteTimeout returns the write timeout.
    89  	WriteTimeout() time.Duration
    90  
    91  	// SetWriteTimeout sets the write timeout.
    92  	SetWriteTimeout(value time.Duration) ConnectionOptions
    93  
    94  	// KeepAlivePeriod returns the keepAlivePeriod.
    95  	KeepAlivePeriod() time.Duration
    96  
    97  	// SetKeepAlivePeriod sets the keepAlivePeriod.
    98  	SetKeepAlivePeriod(value time.Duration) ConnectionOptions
    99  
   100  	// ResetDelay returns the delay before resetting connection.
   101  	ResetDelay() time.Duration
   102  
   103  	// SetResetDelay sets the delay before resetting connection.
   104  	SetResetDelay(value time.Duration) ConnectionOptions
   105  
   106  	// RetryOptions returns the options for connection retrier.
   107  	RetryOptions() retry.Options
   108  
   109  	// SetRetryOptions sets the options for connection retrier.
   110  	SetRetryOptions(value retry.Options) ConnectionOptions
   111  
   112  	// FlushInterval returns the interval for flushing the buffered bytes.
   113  	FlushInterval() time.Duration
   114  
   115  	// SetFlushInterval sets the interval for flushing the buffered bytes.
   116  	SetFlushInterval(value time.Duration) ConnectionOptions
   117  
   118  	// WriteBufferSize returns the buffer size for write.
   119  	WriteBufferSize() int
   120  
   121  	// SetWriteBufferSize sets the buffer size for write.
   122  	SetWriteBufferSize(value int) ConnectionOptions
   123  
   124  	// ReadBufferSize returns the buffer size for read.
   125  	ReadBufferSize() int
   126  
   127  	// SetReadBufferSize sets the buffer size for read.
   128  	SetReadBufferSize(value int) ConnectionOptions
   129  
   130  	// InstrumentOptions returns the instrument options.
   131  	InstrumentOptions() instrument.Options
   132  
   133  	// SetInstrumentOptions sets the instrument options.
   134  	SetInstrumentOptions(value instrument.Options) ConnectionOptions
   135  }
   136  
   137  type connectionOptions struct {
   138  	numConnections  int
   139  	dialTimeout     time.Duration
   140  	writeTimeout    time.Duration
   141  	keepAlivePeriod time.Duration
   142  	resetDelay      time.Duration
   143  	rOpts           retry.Options
   144  	flushInterval   time.Duration
   145  	writeBufferSize int
   146  	readBufferSize  int
   147  	iOpts           instrument.Options
   148  	dialer          ContextDialerFn
   149  }
   150  
   151  // NewConnectionOptions creates ConnectionOptions.
   152  func NewConnectionOptions() ConnectionOptions {
   153  	return &connectionOptions{
   154  		numConnections:  defaultNumConnections,
   155  		dialTimeout:     defaultConnectionDialTimeout,
   156  		writeTimeout:    defaultConnectionWriteTimeout,
   157  		keepAlivePeriod: defaultConnectionKeepAlivePeriod,
   158  		resetDelay:      defaultConnectionResetDelay,
   159  		rOpts:           retry.NewOptions(),
   160  		flushInterval:   defaultConnectionFlushInterval,
   161  		writeBufferSize: defaultConnectionBufferSize,
   162  		readBufferSize:  defaultConnectionBufferSize,
   163  		iOpts:           instrument.NewOptions(),
   164  		dialer:          nil, // Will default to net.Dialer{}.DialContext
   165  	}
   166  }
   167  
   168  func (opts *connectionOptions) NumConnections() int {
   169  	return opts.numConnections
   170  }
   171  
   172  func (opts *connectionOptions) SetNumConnections(value int) ConnectionOptions {
   173  	o := *opts
   174  	o.numConnections = value
   175  	return &o
   176  }
   177  
   178  func (opts *connectionOptions) DialTimeout() time.Duration {
   179  	return opts.dialTimeout
   180  }
   181  
   182  func (opts *connectionOptions) SetDialTimeout(value time.Duration) ConnectionOptions {
   183  	o := *opts
   184  	o.dialTimeout = value
   185  	return &o
   186  }
   187  
   188  func (opts *connectionOptions) ContextDialer() ContextDialerFn {
   189  	return opts.dialer
   190  }
   191  
   192  func (opts *connectionOptions) SetContextDialer(fn ContextDialerFn) ConnectionOptions {
   193  	o := *opts
   194  	o.dialer = fn
   195  	return &o
   196  }
   197  
   198  func (opts *connectionOptions) WriteTimeout() time.Duration {
   199  	return opts.writeTimeout
   200  }
   201  
   202  func (opts *connectionOptions) SetWriteTimeout(value time.Duration) ConnectionOptions {
   203  	o := *opts
   204  	o.writeTimeout = value
   205  	return &o
   206  }
   207  
   208  func (opts *connectionOptions) KeepAlivePeriod() time.Duration {
   209  	return opts.keepAlivePeriod
   210  }
   211  
   212  func (opts *connectionOptions) SetKeepAlivePeriod(value time.Duration) ConnectionOptions {
   213  	o := *opts
   214  	o.keepAlivePeriod = value
   215  	return &o
   216  }
   217  
   218  func (opts *connectionOptions) RetryOptions() retry.Options {
   219  	return opts.rOpts
   220  }
   221  
   222  func (opts *connectionOptions) SetRetryOptions(value retry.Options) ConnectionOptions {
   223  	o := *opts
   224  	o.rOpts = value
   225  	return &o
   226  }
   227  
   228  func (opts *connectionOptions) ResetDelay() time.Duration {
   229  	return opts.resetDelay
   230  }
   231  
   232  func (opts *connectionOptions) SetResetDelay(value time.Duration) ConnectionOptions {
   233  	o := *opts
   234  	o.resetDelay = value
   235  	return &o
   236  }
   237  
   238  func (opts *connectionOptions) FlushInterval() time.Duration {
   239  	return opts.flushInterval
   240  }
   241  
   242  func (opts *connectionOptions) SetFlushInterval(value time.Duration) ConnectionOptions {
   243  	o := *opts
   244  	o.flushInterval = value
   245  	return &o
   246  }
   247  
   248  func (opts *connectionOptions) WriteBufferSize() int {
   249  	return opts.writeBufferSize
   250  }
   251  
   252  func (opts *connectionOptions) SetWriteBufferSize(value int) ConnectionOptions {
   253  	o := *opts
   254  	o.writeBufferSize = value
   255  	return &o
   256  }
   257  
   258  func (opts *connectionOptions) ReadBufferSize() int {
   259  	return opts.readBufferSize
   260  }
   261  
   262  func (opts *connectionOptions) SetReadBufferSize(value int) ConnectionOptions {
   263  	o := *opts
   264  	o.readBufferSize = value
   265  	return &o
   266  }
   267  
   268  func (opts *connectionOptions) InstrumentOptions() instrument.Options {
   269  	return opts.iOpts
   270  }
   271  
   272  func (opts *connectionOptions) SetInstrumentOptions(value instrument.Options) ConnectionOptions {
   273  	o := *opts
   274  	o.iOpts = value
   275  	return &o
   276  }
   277  
   278  // Options configs the writer.
   279  type Options interface {
   280  	// TopicName returns the topic name.
   281  	TopicName() string
   282  
   283  	// SetTopicName sets the topic name.
   284  	SetTopicName(value string) Options
   285  
   286  	// TopicService returns the topic service.
   287  	TopicService() topic.Service
   288  
   289  	// SetTopicService sets the topic service.
   290  	SetTopicService(value topic.Service) Options
   291  
   292  	// TopicWatchInitTimeout returns the timeout for topic watch initialization.
   293  	TopicWatchInitTimeout() time.Duration
   294  
   295  	// SetTopicWatchInitTimeout sets the timeout for topic watch initialization.
   296  	SetTopicWatchInitTimeout(value time.Duration) Options
   297  
   298  	// ServiceDiscovery returns the client to service discovery service.
   299  	ServiceDiscovery() services.Services
   300  
   301  	// SetServiceDiscovery sets the client to service discovery services.
   302  	SetServiceDiscovery(value services.Services) Options
   303  
   304  	// PlacementOptions returns the placement options.
   305  	PlacementOptions() placement.Options
   306  
   307  	// SetPlacementOptions sets the placement options.
   308  	SetPlacementOptions(value placement.Options) Options
   309  
   310  	// PlacementWatchInitTimeout returns the timeout for placement watch initialization.
   311  	PlacementWatchInitTimeout() time.Duration
   312  
   313  	// SetPlacementWatchInitTimeout sets the timeout for placement watch initialization.
   314  	SetPlacementWatchInitTimeout(value time.Duration) Options
   315  
   316  	// MessagePoolOptions returns the options of pool for messages.
   317  	MessagePoolOptions() pool.ObjectPoolOptions
   318  
   319  	// SetMessagePoolOptions sets the options of pool for messages.
   320  	SetMessagePoolOptions(value pool.ObjectPoolOptions) Options
   321  
   322  	// MessageRetryNanosFn returns the MessageRetryNanosFn.
   323  	MessageRetryNanosFn() MessageRetryNanosFn
   324  
   325  	// SetMessageRetryNanosFn sets the MessageRetryNanosFn.
   326  	SetMessageRetryNanosFn(value MessageRetryNanosFn) Options
   327  
   328  	// MessageQueueNewWritesScanInterval returns the interval between scanning
   329  	// message queue for new writes.
   330  	MessageQueueNewWritesScanInterval() time.Duration
   331  
   332  	// SetMessageQueueNewWritesScanInterval sets the interval between scanning
   333  	// message queue for new writes.
   334  	SetMessageQueueNewWritesScanInterval(value time.Duration) Options
   335  
   336  	// MessageQueueFullScanInterval returns the interval between scanning
   337  	// message queue for retriable writes and cleanups.
   338  	MessageQueueFullScanInterval() time.Duration
   339  
   340  	// SetMessageQueueFullScanInterval sets the interval between scanning
   341  	// message queue for retriable writes and cleanups.
   342  	SetMessageQueueFullScanInterval(value time.Duration) Options
   343  
   344  	// MessageQueueScanBatchSize returns the batch size for queue scan.
   345  	MessageQueueScanBatchSize() int
   346  
   347  	// SetMessageQueueScanBatchSize sets the batch size for queue scan.
   348  	SetMessageQueueScanBatchSize(value int) Options
   349  
   350  	// InitialAckMapSize returns the initial size of the ack map.
   351  	InitialAckMapSize() int
   352  
   353  	// SetInitialAckMapSize sets the initial size of the ack map.
   354  	SetInitialAckMapSize(value int) Options
   355  
   356  	// CloseCheckInterval returns the close check interval.
   357  	CloseCheckInterval() time.Duration
   358  
   359  	// SetCloseCheckInterval sets the close check interval.
   360  	SetCloseCheckInterval(value time.Duration) Options
   361  
   362  	// AckErrorRetryOptions returns the retrier for ack errors.
   363  	AckErrorRetryOptions() retry.Options
   364  
   365  	// SetAckErrorRetryOptions sets the retrier for ack errors.
   366  	SetAckErrorRetryOptions(value retry.Options) Options
   367  
   368  	// EncoderOptions returns the encoder's options.
   369  	EncoderOptions() proto.Options
   370  
   371  	// SetEncoderOptions sets the encoder's options.
   372  	SetEncoderOptions(value proto.Options) Options
   373  
   374  	// DecoderOptions returns the decoder's options.
   375  	DecoderOptions() proto.Options
   376  
   377  	// SetDecoderOptions sets the decoder's options.
   378  	SetDecoderOptions(value proto.Options) Options
   379  
   380  	// ConnectionOptions returns the options for connections.
   381  	ConnectionOptions() ConnectionOptions
   382  
   383  	// SetConnectionOptions sets the options for connections.
   384  	SetConnectionOptions(value ConnectionOptions) Options
   385  
   386  	// InstrumentOptions returns the instrument options.
   387  	InstrumentOptions() instrument.Options
   388  
   389  	// SetInstrumentOptions sets the instrument options.
   390  	SetInstrumentOptions(value instrument.Options) Options
   391  
   392  	// IgnoreCutoffCutover returns a flag indicating whether cutoff/cutover timestamps are ignored.
   393  	IgnoreCutoffCutover() bool
   394  
   395  	// SetIgnoreCutoffCutover sets a flag controlling whether cutoff/cutover timestamps are ignored.
   396  	SetIgnoreCutoffCutover(value bool) Options
   397  
   398  	// WithoutConsumerScope disables the consumer scope for metrics. For large m3msg deployments the consumer
   399  	// scope can add a lot of cardinality to the metrics.
   400  	WithoutConsumerScope() bool
   401  
   402  	// SetWithoutConsumerScope sets the value for WithoutConsumerScope.
   403  	SetWithoutConsumerScope(value bool) Options
   404  }
   405  
   406  type writerOptions struct {
   407  	topicName                         string
   408  	topicService                      topic.Service
   409  	topicWatchInitTimeout             time.Duration
   410  	services                          services.Services
   411  	placementOpts                     placement.Options
   412  	placementWatchInitTimeout         time.Duration
   413  	messageRetryNanosFn               MessageRetryNanosFn
   414  	messagePoolOptions                pool.ObjectPoolOptions
   415  	messageQueueNewWritesScanInterval time.Duration
   416  	messageQueueFullScanInterval      time.Duration
   417  	messageQueueScanBatchSize         int
   418  	initialAckMapSize                 int
   419  	closeCheckInterval                time.Duration
   420  	ackErrRetryOpts                   retry.Options
   421  	encOpts                           proto.Options
   422  	decOpts                           proto.Options
   423  	cOpts                             ConnectionOptions
   424  	iOpts                             instrument.Options
   425  	ignoreCutoffCutover               bool
   426  	withoutConsumerScope              bool
   427  }
   428  
   429  // NewOptions creates Options.
   430  func NewOptions() Options {
   431  	messageRetryOpts := retry.NewOptions().
   432  		SetInitialBackoff(defaultWriterRetryInitialBackoff)
   433  	return &writerOptions{
   434  		topicWatchInitTimeout:             defaultTopicWatchInitTimeout,
   435  		placementOpts:                     placement.NewOptions(),
   436  		placementWatchInitTimeout:         defaultPlacementWatchInitTimeout,
   437  		messageRetryNanosFn:               NextRetryNanosFn(messageRetryOpts),
   438  		messageQueueNewWritesScanInterval: defaultMessageQueueNewWritesScanInterval,
   439  		messageQueueFullScanInterval:      defaultMessageQueueFullScanInterval,
   440  		messageQueueScanBatchSize:         defaultMessageQueueScanBatchSize,
   441  		initialAckMapSize:                 defaultInitialAckMapSize,
   442  		closeCheckInterval:                defaultCloseCheckInterval,
   443  		ackErrRetryOpts:                   retry.NewOptions(),
   444  		encOpts:                           proto.NewOptions(),
   445  		decOpts:                           proto.NewOptions(),
   446  		cOpts:                             NewConnectionOptions(),
   447  		iOpts:                             instrument.NewOptions(),
   448  	}
   449  }
   450  
   451  func (opts *writerOptions) TopicName() string {
   452  	return opts.topicName
   453  }
   454  
   455  func (opts *writerOptions) SetTopicName(value string) Options {
   456  	o := *opts
   457  	o.topicName = value
   458  	return &o
   459  }
   460  
   461  func (opts *writerOptions) TopicService() topic.Service {
   462  	return opts.topicService
   463  }
   464  
   465  func (opts *writerOptions) SetTopicService(value topic.Service) Options {
   466  	o := *opts
   467  	o.topicService = value
   468  	return &o
   469  }
   470  
   471  func (opts *writerOptions) TopicWatchInitTimeout() time.Duration {
   472  	return opts.topicWatchInitTimeout
   473  }
   474  
   475  func (opts *writerOptions) SetTopicWatchInitTimeout(value time.Duration) Options {
   476  	o := *opts
   477  	o.topicWatchInitTimeout = value
   478  	return &o
   479  }
   480  
   481  func (opts *writerOptions) ServiceDiscovery() services.Services {
   482  	return opts.services
   483  }
   484  
   485  func (opts *writerOptions) SetServiceDiscovery(value services.Services) Options {
   486  	o := *opts
   487  	o.services = value
   488  	return &o
   489  }
   490  
   491  func (opts *writerOptions) PlacementOptions() placement.Options {
   492  	return opts.placementOpts
   493  }
   494  
   495  func (opts *writerOptions) SetPlacementOptions(value placement.Options) Options {
   496  	o := *opts
   497  	o.placementOpts = value
   498  	return &o
   499  }
   500  
   501  func (opts *writerOptions) PlacementWatchInitTimeout() time.Duration {
   502  	return opts.placementWatchInitTimeout
   503  }
   504  
   505  func (opts *writerOptions) SetPlacementWatchInitTimeout(value time.Duration) Options {
   506  	o := *opts
   507  	o.placementWatchInitTimeout = value
   508  	return &o
   509  }
   510  
   511  func (opts *writerOptions) MessagePoolOptions() pool.ObjectPoolOptions {
   512  	return opts.messagePoolOptions
   513  }
   514  
   515  func (opts *writerOptions) SetMessagePoolOptions(value pool.ObjectPoolOptions) Options {
   516  	o := *opts
   517  	o.messagePoolOptions = value
   518  	return &o
   519  }
   520  
   521  func (opts *writerOptions) MessageRetryNanosFn() MessageRetryNanosFn {
   522  	return opts.messageRetryNanosFn
   523  }
   524  
   525  func (opts *writerOptions) SetMessageRetryNanosFn(value MessageRetryNanosFn) Options {
   526  	o := *opts
   527  	o.messageRetryNanosFn = value
   528  	return &o
   529  }
   530  
   531  func (opts *writerOptions) MessageQueueNewWritesScanInterval() time.Duration {
   532  	return opts.messageQueueNewWritesScanInterval
   533  }
   534  
   535  func (opts *writerOptions) SetMessageQueueNewWritesScanInterval(value time.Duration) Options {
   536  	o := *opts
   537  	o.messageQueueNewWritesScanInterval = value
   538  	return &o
   539  }
   540  
   541  func (opts *writerOptions) MessageQueueFullScanInterval() time.Duration {
   542  	return opts.messageQueueFullScanInterval
   543  }
   544  
   545  func (opts *writerOptions) SetMessageQueueFullScanInterval(value time.Duration) Options {
   546  	o := *opts
   547  	o.messageQueueFullScanInterval = value
   548  	return &o
   549  }
   550  
   551  func (opts *writerOptions) MessageQueueScanBatchSize() int {
   552  	return opts.messageQueueScanBatchSize
   553  }
   554  
   555  func (opts *writerOptions) SetMessageQueueScanBatchSize(value int) Options {
   556  	o := *opts
   557  	o.messageQueueScanBatchSize = value
   558  	return &o
   559  }
   560  
   561  func (opts *writerOptions) InitialAckMapSize() int {
   562  	return opts.initialAckMapSize
   563  }
   564  
   565  func (opts *writerOptions) SetInitialAckMapSize(value int) Options {
   566  	o := *opts
   567  	o.initialAckMapSize = value
   568  	return &o
   569  }
   570  
   571  func (opts *writerOptions) CloseCheckInterval() time.Duration {
   572  	return opts.closeCheckInterval
   573  }
   574  
   575  func (opts *writerOptions) SetCloseCheckInterval(value time.Duration) Options {
   576  	o := *opts
   577  	o.closeCheckInterval = value
   578  	return &o
   579  }
   580  
   581  func (opts *writerOptions) AckErrorRetryOptions() retry.Options {
   582  	return opts.ackErrRetryOpts
   583  }
   584  
   585  func (opts *writerOptions) SetAckErrorRetryOptions(value retry.Options) Options {
   586  	o := *opts
   587  	o.ackErrRetryOpts = value
   588  	return &o
   589  }
   590  
   591  func (opts *writerOptions) EncoderOptions() proto.Options {
   592  	return opts.encOpts
   593  }
   594  
   595  func (opts *writerOptions) SetEncoderOptions(value proto.Options) Options {
   596  	o := *opts
   597  	o.encOpts = value
   598  	return &o
   599  }
   600  
   601  func (opts *writerOptions) DecoderOptions() proto.Options {
   602  	return opts.decOpts
   603  }
   604  
   605  func (opts *writerOptions) SetDecoderOptions(value proto.Options) Options {
   606  	o := *opts
   607  	o.decOpts = value
   608  	return &o
   609  }
   610  
   611  func (opts *writerOptions) ConnectionOptions() ConnectionOptions {
   612  	return opts.cOpts
   613  }
   614  
   615  func (opts *writerOptions) SetConnectionOptions(value ConnectionOptions) Options {
   616  	o := *opts
   617  	o.cOpts = value
   618  	return &o
   619  }
   620  
   621  func (opts *writerOptions) InstrumentOptions() instrument.Options {
   622  	return opts.iOpts
   623  }
   624  
   625  func (opts *writerOptions) SetInstrumentOptions(value instrument.Options) Options {
   626  	o := *opts
   627  	o.iOpts = value
   628  	return &o
   629  }
   630  
   631  func (opts *writerOptions) IgnoreCutoffCutover() bool {
   632  	return opts.ignoreCutoffCutover
   633  }
   634  
   635  func (opts *writerOptions) SetIgnoreCutoffCutover(value bool) Options {
   636  	o := *opts
   637  	o.ignoreCutoffCutover = value
   638  	return &o
   639  }
   640  
   641  func (opts *writerOptions) WithoutConsumerScope() bool {
   642  	return opts.withoutConsumerScope
   643  }
   644  
   645  func (opts *writerOptions) SetWithoutConsumerScope(value bool) Options {
   646  	o := *opts
   647  	o.withoutConsumerScope = value
   648  	return &o
   649  }