github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/aggregator/client/conn_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 client
    22  
    23  import (
    24  	"time"
    25  
    26  	"github.com/m3db/m3/src/x/clock"
    27  	"github.com/m3db/m3/src/x/instrument"
    28  	xio "github.com/m3db/m3/src/x/io"
    29  	xnet "github.com/m3db/m3/src/x/net"
    30  	"github.com/m3db/m3/src/x/retry"
    31  )
    32  
    33  const (
    34  	defaultConnectionTimeout            = 1 * time.Second
    35  	defaultConnectionKeepAlive          = true
    36  	defaultWriteTimeout                 = 15 * time.Second
    37  	defaultInitReconnectThreshold       = 1
    38  	defaultMaxReconnectThreshold        = 4
    39  	defaultReconnectThresholdMultiplier = 2
    40  	defaultMaxReconnectDuration         = 20 * time.Second
    41  	defaultWriteRetryInitialBackoff     = 0
    42  	defaultWriteRetryBackoffFactor      = 2
    43  	defaultWriteRetryMaxBackoff         = time.Second
    44  	defaultWriteRetryMaxRetries         = 1
    45  	defaultWriteRetryJitterEnabled      = true
    46  )
    47  
    48  // ConnectionOptions provides a set of options for tcp connections.
    49  type ConnectionOptions interface {
    50  	// SetInstrumentOptions sets the instrument options.
    51  	SetClockOptions(value clock.Options) ConnectionOptions
    52  
    53  	// ClockOptions returns the clock options.
    54  	ClockOptions() clock.Options
    55  
    56  	// SetInstrumentOptions sets the instrument options.
    57  	SetInstrumentOptions(value instrument.Options) ConnectionOptions
    58  
    59  	// InstrumentOptions returns the instrument options.
    60  	InstrumentOptions() instrument.Options
    61  
    62  	// SetConnectionTimeout sets the timeout for establishing connections.
    63  	SetConnectionTimeout(value time.Duration) ConnectionOptions
    64  
    65  	// ConnectionTimeout returns the timeout for establishing connections.
    66  	ConnectionTimeout() time.Duration
    67  
    68  	// SetConnectionKeepAlive sets the keepAlive for the connection.
    69  	SetConnectionKeepAlive(value bool) ConnectionOptions
    70  
    71  	// ConnectionKeepAlive returns the keepAlive for the connection.
    72  	ConnectionKeepAlive() bool
    73  
    74  	// SetWriteTimeout sets the timeout for writing data.
    75  	SetWriteTimeout(value time.Duration) ConnectionOptions
    76  
    77  	// WriteTimeout returns the timeout for writing data.
    78  	WriteTimeout() time.Duration
    79  
    80  	// SetInitReconnectThreshold sets the initial threshold for re-establshing connections.
    81  	SetInitReconnectThreshold(value int) ConnectionOptions
    82  
    83  	// InitReconnectThreshold returns the initial threshold for re-establishing connections.
    84  	InitReconnectThreshold() int
    85  
    86  	// SetMaxReconnectThreshold sets the max threshold for re-establishing connections.
    87  	SetMaxReconnectThreshold(value int) ConnectionOptions
    88  
    89  	// MaxReconnectThreshold returns the max threshold for re-establishing connections.
    90  	MaxReconnectThreshold() int
    91  
    92  	// SetReconnectThresholdMultiplier sets the threshold multiplier.
    93  	SetReconnectThresholdMultiplier(value int) ConnectionOptions
    94  
    95  	// ReconnectThresholdMultiplier returns the threshold multiplier.
    96  	ReconnectThresholdMultiplier() int
    97  
    98  	// SetMaxReconnectDuration sets the max duration between attempts to re-establish connections.
    99  	SetMaxReconnectDuration(value time.Duration) ConnectionOptions
   100  
   101  	// MaxReconnectDuration returns the max duration between attempts to re-establish connections.
   102  	MaxReconnectDuration() time.Duration
   103  
   104  	// SetWriteRetryOptions sets the retry options for retrying failed writes.
   105  	SetWriteRetryOptions(value retry.Options) ConnectionOptions
   106  
   107  	// WriteRetryOptions returns the retry options for retrying failed writes.
   108  	WriteRetryOptions() retry.Options
   109  
   110  	// SetRWOptions sets RW options.
   111  	SetRWOptions(value xio.Options) ConnectionOptions
   112  
   113  	// RWOptions returns the RW options.
   114  	RWOptions() xio.Options
   115  
   116  	// ContextDialer allows customizing the way an aggregator client the aggregator, at the TCP layer.
   117  	// By default, this is:
   118  	// (&net.ContextDialer{}).DialContext. This can be used to do a variety of things, such as forwarding a connection
   119  	// over a proxy.
   120  	// NOTE: if your xnet.ContextDialerFn returns anything other a *net.TCPConn, TCP options such as KeepAlivePeriod
   121  	// will *not* be applied automatically. It is your responsibility to make sure these get applied as needed in
   122  	// your custom xnet.ContextDialerFn.
   123  	ContextDialer() xnet.ContextDialerFn
   124  	// SetContextDialer sets ContextDialer() -- see that method.
   125  	SetContextDialer(dialer xnet.ContextDialerFn) ConnectionOptions
   126  }
   127  
   128  type connectionOptions struct {
   129  	clockOpts      clock.Options
   130  	instrumentOpts instrument.Options
   131  	writeRetryOpts retry.Options
   132  	rwOpts         xio.Options
   133  	connTimeout    time.Duration
   134  	writeTimeout   time.Duration
   135  	maxDuration    time.Duration
   136  	initThreshold  int
   137  	maxThreshold   int
   138  	multiplier     int
   139  	connKeepAlive  bool
   140  	dialer         xnet.ContextDialerFn
   141  }
   142  
   143  // NewConnectionOptions create a new set of connection options.
   144  func NewConnectionOptions() ConnectionOptions {
   145  	defaultWriteRetryOpts := retry.NewOptions().
   146  		SetInitialBackoff(defaultWriteRetryInitialBackoff).
   147  		SetBackoffFactor(defaultWriteRetryBackoffFactor).
   148  		SetMaxBackoff(defaultWriteRetryMaxBackoff).
   149  		SetMaxRetries(defaultWriteRetryMaxRetries).
   150  		SetJitter(defaultWriteRetryJitterEnabled)
   151  	return &connectionOptions{
   152  		clockOpts:      clock.NewOptions(),
   153  		instrumentOpts: instrument.NewOptions(),
   154  		connTimeout:    defaultConnectionTimeout,
   155  		connKeepAlive:  defaultConnectionKeepAlive,
   156  		writeTimeout:   defaultWriteTimeout,
   157  		initThreshold:  defaultInitReconnectThreshold,
   158  		maxThreshold:   defaultMaxReconnectThreshold,
   159  		multiplier:     defaultReconnectThresholdMultiplier,
   160  		maxDuration:    defaultMaxReconnectDuration,
   161  		writeRetryOpts: defaultWriteRetryOpts,
   162  		rwOpts:         xio.NewOptions(),
   163  		dialer:         nil, // Will default to net.Dialer{}.DialContext
   164  	}
   165  }
   166  
   167  func (o *connectionOptions) SetClockOptions(value clock.Options) ConnectionOptions {
   168  	opts := *o
   169  	opts.clockOpts = value
   170  	return &opts
   171  }
   172  
   173  func (o *connectionOptions) ClockOptions() clock.Options {
   174  	return o.clockOpts
   175  }
   176  
   177  func (o *connectionOptions) SetInstrumentOptions(value instrument.Options) ConnectionOptions {
   178  	opts := *o
   179  	opts.instrumentOpts = value
   180  	return &opts
   181  }
   182  
   183  func (o *connectionOptions) InstrumentOptions() instrument.Options {
   184  	return o.instrumentOpts
   185  }
   186  
   187  func (o *connectionOptions) SetConnectionTimeout(value time.Duration) ConnectionOptions {
   188  	opts := *o
   189  	opts.connTimeout = value
   190  	return &opts
   191  }
   192  
   193  func (o *connectionOptions) ConnectionTimeout() time.Duration {
   194  	return o.connTimeout
   195  }
   196  
   197  func (o *connectionOptions) SetConnectionKeepAlive(value bool) ConnectionOptions {
   198  	opts := *o
   199  	opts.connKeepAlive = value
   200  	return &opts
   201  }
   202  
   203  func (o *connectionOptions) ConnectionKeepAlive() bool {
   204  	return o.connKeepAlive
   205  }
   206  
   207  func (o *connectionOptions) SetWriteTimeout(value time.Duration) ConnectionOptions {
   208  	opts := *o
   209  	opts.writeTimeout = value
   210  	return &opts
   211  }
   212  
   213  func (o *connectionOptions) WriteTimeout() time.Duration {
   214  	return o.writeTimeout
   215  }
   216  
   217  func (o *connectionOptions) SetInitReconnectThreshold(value int) ConnectionOptions {
   218  	opts := *o
   219  	opts.initThreshold = value
   220  	return &opts
   221  }
   222  
   223  func (o *connectionOptions) InitReconnectThreshold() int {
   224  	return o.initThreshold
   225  }
   226  
   227  func (o *connectionOptions) SetMaxReconnectThreshold(value int) ConnectionOptions {
   228  	opts := *o
   229  	opts.maxThreshold = value
   230  	return &opts
   231  }
   232  
   233  func (o *connectionOptions) MaxReconnectThreshold() int {
   234  	return o.maxThreshold
   235  }
   236  
   237  func (o *connectionOptions) SetReconnectThresholdMultiplier(value int) ConnectionOptions {
   238  	opts := *o
   239  	opts.multiplier = value
   240  	return &opts
   241  }
   242  
   243  func (o *connectionOptions) ReconnectThresholdMultiplier() int {
   244  	return o.multiplier
   245  }
   246  
   247  func (o *connectionOptions) SetMaxReconnectDuration(value time.Duration) ConnectionOptions {
   248  	opts := *o
   249  	opts.maxDuration = value
   250  	return &opts
   251  }
   252  
   253  func (o *connectionOptions) MaxReconnectDuration() time.Duration {
   254  	return o.maxDuration
   255  }
   256  
   257  func (o *connectionOptions) SetWriteRetryOptions(value retry.Options) ConnectionOptions {
   258  	opts := *o
   259  	opts.writeRetryOpts = value
   260  	return &opts
   261  }
   262  
   263  func (o *connectionOptions) WriteRetryOptions() retry.Options {
   264  	return o.writeRetryOpts
   265  }
   266  
   267  func (o *connectionOptions) SetRWOptions(value xio.Options) ConnectionOptions {
   268  	opts := *o
   269  	opts.rwOpts = value
   270  	return &opts
   271  }
   272  
   273  func (o *connectionOptions) RWOptions() xio.Options {
   274  	return o.rwOpts
   275  }
   276  
   277  func (o *connectionOptions) ContextDialer() xnet.ContextDialerFn {
   278  	return o.dialer
   279  }
   280  
   281  // SetContextDialer see ContextDialer.
   282  func (o *connectionOptions) SetContextDialer(dialer xnet.ContextDialerFn) ConnectionOptions {
   283  	opts := *o
   284  	opts.dialer = dialer
   285  	return &opts
   286  }