gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/grpc/dialoptions.go (about)

     1  /*
     2   *
     3   * Copyright 2018 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package grpc
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  	"gitee.com/zhaochuninhefei/gmgo/grpc/encoding"
    25  	"net"
    26  	"time"
    27  
    28  	"gitee.com/zhaochuninhefei/gmgo/grpc/backoff"
    29  	"gitee.com/zhaochuninhefei/gmgo/grpc/balancer"
    30  	"gitee.com/zhaochuninhefei/gmgo/grpc/credentials"
    31  	"gitee.com/zhaochuninhefei/gmgo/grpc/credentials/insecure"
    32  	"gitee.com/zhaochuninhefei/gmgo/grpc/internal"
    33  	internalbackoff "gitee.com/zhaochuninhefei/gmgo/grpc/internal/backoff"
    34  	"gitee.com/zhaochuninhefei/gmgo/grpc/internal/transport"
    35  	"gitee.com/zhaochuninhefei/gmgo/grpc/keepalive"
    36  	"gitee.com/zhaochuninhefei/gmgo/grpc/resolver"
    37  	"gitee.com/zhaochuninhefei/gmgo/grpc/stats"
    38  )
    39  
    40  // dialOptions configure a Dial call. dialOptions are set by the DialOption
    41  // values passed to Dial.
    42  type dialOptions struct {
    43  	unaryInt  UnaryClientInterceptor
    44  	streamInt StreamClientInterceptor
    45  
    46  	chainUnaryInts  []UnaryClientInterceptor
    47  	chainStreamInts []StreamClientInterceptor
    48  
    49  	cp              Compressor
    50  	dc              Decompressor
    51  	bs              internalbackoff.Strategy
    52  	block           bool
    53  	returnLastError bool
    54  	timeout         time.Duration
    55  	scChan          <-chan ServiceConfig
    56  	authority       string
    57  	copts           transport.ConnectOptions
    58  	callOptions     []CallOption
    59  	// This is used by WithBalancerName dial option.
    60  	balancerBuilder             balancer.Builder
    61  	channelzParentID            int64
    62  	disableServiceConfig        bool
    63  	disableRetry                bool
    64  	disableHealthCheck          bool
    65  	healthCheckFunc             internal.HealthChecker
    66  	minConnectTimeout           func() time.Duration
    67  	defaultServiceConfig        *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON.
    68  	defaultServiceConfigRawJSON *string
    69  	resolvers                   []resolver.Builder
    70  }
    71  
    72  // DialOption configures how we set up the connection.
    73  type DialOption interface {
    74  	apply(*dialOptions)
    75  }
    76  
    77  // EmptyDialOption does not alter the dial configuration. It can be embedded in
    78  // another structure to build custom dial options.
    79  //
    80  // Experimental
    81  //
    82  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
    83  // later release.
    84  type EmptyDialOption struct{}
    85  
    86  func (EmptyDialOption) apply(*dialOptions) {}
    87  
    88  // funcDialOption wraps a function that modifies dialOptions into an
    89  // implementation of the DialOption interface.
    90  type funcDialOption struct {
    91  	f func(*dialOptions)
    92  }
    93  
    94  func (fdo *funcDialOption) apply(do *dialOptions) {
    95  	fdo.f(do)
    96  }
    97  
    98  func newFuncDialOption(f func(*dialOptions)) *funcDialOption {
    99  	return &funcDialOption{
   100  		f: f,
   101  	}
   102  }
   103  
   104  // WithWriteBufferSize determines how much data can be batched before doing a
   105  // write on the wire. The corresponding memory allocation for this buffer will
   106  // be twice the size to keep syscalls low. The default value for this buffer is
   107  // 32KB.
   108  //
   109  // Zero will disable the write buffer such that each write will be on underlying
   110  // connection. Note: A Send call may not directly translate to a write.
   111  func WithWriteBufferSize(s int) DialOption {
   112  	return newFuncDialOption(func(o *dialOptions) {
   113  		o.copts.WriteBufferSize = s
   114  	})
   115  }
   116  
   117  // WithReadBufferSize lets you set the size of read buffer, this determines how
   118  // much data can be read at most for each read syscall.
   119  //
   120  // The default value for this buffer is 32KB. Zero will disable read buffer for
   121  // a connection so data framer can access the underlying conn directly.
   122  func WithReadBufferSize(s int) DialOption {
   123  	return newFuncDialOption(func(o *dialOptions) {
   124  		o.copts.ReadBufferSize = s
   125  	})
   126  }
   127  
   128  // WithInitialWindowSize returns a DialOption which sets the value for initial
   129  // window size on a stream. The lower bound for window size is 64K and any value
   130  // smaller than that will be ignored.
   131  func WithInitialWindowSize(s int32) DialOption {
   132  	return newFuncDialOption(func(o *dialOptions) {
   133  		o.copts.InitialWindowSize = s
   134  	})
   135  }
   136  
   137  // WithInitialConnWindowSize returns a DialOption which sets the value for
   138  // initial window size on a connection. The lower bound for window size is 64K
   139  // and any value smaller than that will be ignored.
   140  func WithInitialConnWindowSize(s int32) DialOption {
   141  	return newFuncDialOption(func(o *dialOptions) {
   142  		o.copts.InitialConnWindowSize = s
   143  	})
   144  }
   145  
   146  // WithMaxMsgSize returns a DialOption which sets the maximum message size the
   147  // client can receive.
   148  //
   149  // Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead.  Will
   150  // be supported throughout 1.x.
   151  //goland:noinspection GoUnusedExportedFunction
   152  func WithMaxMsgSize(s int) DialOption {
   153  	return WithDefaultCallOptions(MaxCallRecvMsgSize(s))
   154  }
   155  
   156  // WithDefaultCallOptions returns a DialOption which sets the default
   157  // CallOptions for calls over the connection.
   158  func WithDefaultCallOptions(cos ...CallOption) DialOption {
   159  	return newFuncDialOption(func(o *dialOptions) {
   160  		o.callOptions = append(o.callOptions, cos...)
   161  	})
   162  }
   163  
   164  // WithCodec returns a DialOption which sets a codec for message marshaling and
   165  // unmarshaling.
   166  //
   167  // ToDeprecated: use WithDefaultCallOptions(ForceCodec(_)) instead.  Will be
   168  // supported throughout 1.x.
   169  func WithCodec(c encoding.Codec) DialOption {
   170  	return WithDefaultCallOptions(CallCustomCodec(c))
   171  }
   172  
   173  // WithCompressor returns a DialOption which sets a Compressor to use for
   174  // message compression. It has lower priority than the compressor set by the
   175  // UseCompressor CallOption.
   176  //
   177  // ToDeprecated: use UseCompressor instead.  Will be supported throughout 1.x.
   178  func WithCompressor(cp Compressor) DialOption {
   179  	return newFuncDialOption(func(o *dialOptions) {
   180  		o.cp = cp
   181  	})
   182  }
   183  
   184  // WithDecompressor returns a DialOption which sets a Decompressor to use for
   185  // incoming message decompression.  If incoming response messages are encoded
   186  // using the decompressor's Type(), it will be used.  Otherwise, the message
   187  // encoding will be used to look up the compressor registered via
   188  // encoding.RegisterCompressor, which will then be used to decompress the
   189  // message.  If no compressor is registered for the encoding, an Unimplemented
   190  // status error will be returned.
   191  //
   192  // ToDeprecated: use encoding.RegisterCompressor instead.  Will be supported
   193  // throughout 1.x.
   194  func WithDecompressor(dc Decompressor) DialOption {
   195  	return newFuncDialOption(func(o *dialOptions) {
   196  		o.dc = dc
   197  	})
   198  }
   199  
   200  // WithBalancerName sets the balancer that the ClientConn will be initialized
   201  // with. Balancer registered with balancerName will be used. This function
   202  // panics if no balancer was registered by balancerName.
   203  //
   204  // The balancer cannot be overridden by balancer option specified by service
   205  // config.
   206  //
   207  // ToDeprecated: use WithDefaultServiceConfig and WithDisableServiceConfig
   208  // instead.  Will be removed in a future 1.x release.
   209  func WithBalancerName(balancerName string) DialOption {
   210  	builder := balancer.Get(balancerName)
   211  	if builder == nil {
   212  		panic(fmt.Sprintf("grpc.WithBalancerName: no balancer is registered for name %v", balancerName))
   213  	}
   214  	return newFuncDialOption(func(o *dialOptions) {
   215  		o.balancerBuilder = builder
   216  	})
   217  }
   218  
   219  // WithServiceConfig returns a DialOption which has a channel to read the
   220  // service configuration.
   221  //
   222  // ToDeprecated: service config should be received through name resolver or via
   223  // WithDefaultServiceConfig, as specified at
   224  // https://github.com/grpc/grpc/blob/master/doc/service_config.md.  Will be
   225  // removed in a future 1.x release.
   226  func WithServiceConfig(c <-chan ServiceConfig) DialOption {
   227  	return newFuncDialOption(func(o *dialOptions) {
   228  		o.scChan = c
   229  	})
   230  }
   231  
   232  // WithConnectParams configures the ClientConn to use the provided ConnectParams
   233  // for creating and maintaining connections to servers.
   234  //
   235  // The backoff configuration specified as part of the ConnectParams overrides
   236  // all defaults specified in
   237  // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. Consider
   238  // using the backoff.DefaultConfig as a base, in cases where you want to
   239  // override only a subset of the backoff configuration.
   240  func WithConnectParams(p ConnectParams) DialOption {
   241  	return newFuncDialOption(func(o *dialOptions) {
   242  		o.bs = internalbackoff.Exponential{Config: p.Backoff}
   243  		o.minConnectTimeout = func() time.Duration {
   244  			return p.MinConnectTimeout
   245  		}
   246  	})
   247  }
   248  
   249  // WithBackoffMaxDelay configures the dialer to use the provided maximum delay
   250  // when backing off after failed connection attempts.
   251  //
   252  // ToDeprecated: use WithConnectParams instead. Will be supported throughout 1.x.
   253  func WithBackoffMaxDelay(md time.Duration) DialOption {
   254  	return WithBackoffConfig(BackoffConfig{MaxDelay: md})
   255  }
   256  
   257  // WithBackoffConfig configures the dialer to use the provided backoff
   258  // parameters after connection failures.
   259  //
   260  // ToDeprecated: use WithConnectParams instead. Will be supported throughout 1.x.
   261  func WithBackoffConfig(b BackoffConfig) DialOption {
   262  	bc := backoff.DefaultConfig
   263  	bc.MaxDelay = b.MaxDelay
   264  	return withBackoff(internalbackoff.Exponential{Config: bc})
   265  }
   266  
   267  // withBackoff sets the backoff strategy used for connectRetryNum after a failed
   268  // connection attempt.
   269  //
   270  // This can be exported if arbitrary backoff strategies are allowed by gRPC.
   271  func withBackoff(bs internalbackoff.Strategy) DialOption {
   272  	return newFuncDialOption(func(o *dialOptions) {
   273  		o.bs = bs
   274  	})
   275  }
   276  
   277  // WithBlock returns a DialOption which makes callers of Dial block until the
   278  // underlying connection is up. Without this, Dial returns immediately and
   279  // connecting the server happens in background.
   280  func WithBlock() DialOption {
   281  	return newFuncDialOption(func(o *dialOptions) {
   282  		o.block = true
   283  	})
   284  }
   285  
   286  // WithReturnConnectionError returns a DialOption which makes the client connection
   287  // return a string containing both the last connection error that occurred and
   288  // the context.DeadlineExceeded error.
   289  // Implies WithBlock()
   290  //
   291  // Experimental
   292  //
   293  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   294  // later release.
   295  func WithReturnConnectionError() DialOption {
   296  	return newFuncDialOption(func(o *dialOptions) {
   297  		o.block = true
   298  		o.returnLastError = true
   299  	})
   300  }
   301  
   302  // WithInsecure returns a DialOption which disables transport security for this
   303  // ClientConn. Under the hood, it uses insecure.NewCredentials().
   304  //
   305  // Note that using this DialOption with per-RPC credentials (through
   306  // WithCredentialsBundle or WithPerRPCCredentials) which require transport
   307  // security is incompatible and will cause grpc.Dial() to fail.
   308  //
   309  // Deprecated: use WithTransportCredentials and insecure.NewCredentials() instead.
   310  // Will be supported throughout 1.x.
   311  func WithInsecure() DialOption {
   312  	return newFuncDialOption(func(o *dialOptions) {
   313  		o.copts.TransportCredentials = insecure.NewCredentials()
   314  	})
   315  }
   316  
   317  // WithNoProxy returns a DialOption which disables the use of proxies for this
   318  // ClientConn. This is ignored if WithDialer or WithContextDialer are used.
   319  //
   320  // Experimental
   321  //
   322  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   323  // later release.
   324  //goland:noinspection GoUnusedExportedFunction
   325  func WithNoProxy() DialOption {
   326  	return newFuncDialOption(func(o *dialOptions) {
   327  		o.copts.UseProxy = false
   328  	})
   329  }
   330  
   331  // WithTransportCredentials returns a DialOption which configures a connection
   332  // level security credentials (e.g., TLS/SSL). This should not be used together
   333  // with WithCredentialsBundle.
   334  func WithTransportCredentials(creds credentials.TransportCredentials) DialOption {
   335  	return newFuncDialOption(func(o *dialOptions) {
   336  		o.copts.TransportCredentials = creds
   337  	})
   338  }
   339  
   340  // WithPerRPCCredentials returns a DialOption which sets credentials and places
   341  // auth state on each outbound RPC.
   342  func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption {
   343  	return newFuncDialOption(func(o *dialOptions) {
   344  		o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds)
   345  	})
   346  }
   347  
   348  // WithCredentialsBundle returns a DialOption to set a credentials bundle for
   349  // the ClientConn.WithCreds. This should not be used together with
   350  // WithTransportCredentials.
   351  //
   352  // Experimental
   353  //
   354  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   355  // later release.
   356  func WithCredentialsBundle(b credentials.Bundle) DialOption {
   357  	return newFuncDialOption(func(o *dialOptions) {
   358  		o.copts.CredsBundle = b
   359  	})
   360  }
   361  
   362  // WithTimeout returns a DialOption that configures a timeout for dialing a
   363  // ClientConn initially. This is valid if and only if WithBlock() is present.
   364  //
   365  // Deprecated: use DialContext instead of Dial and context.WithTimeout
   366  // instead.  Will be supported throughout 1.x.
   367  func WithTimeout(d time.Duration) DialOption {
   368  	return newFuncDialOption(func(o *dialOptions) {
   369  		o.timeout = d
   370  	})
   371  }
   372  
   373  // WithContextDialer returns a DialOption that sets a dialer to create
   374  // connections. If FailOnNonTempDialError() is set to true, and an error is
   375  // returned by f, gRPC checks the error's Temporary() method to decide if it
   376  // should try to reconnect to the network address.
   377  func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption {
   378  	return newFuncDialOption(func(o *dialOptions) {
   379  		o.copts.Dialer = f
   380  	})
   381  }
   382  
   383  func init() {
   384  	internal.WithHealthCheckFunc = withHealthCheckFunc
   385  }
   386  
   387  // WithDialer returns a DialOption that specifies a function to use for dialing
   388  // network addresses. If FailOnNonTempDialError() is set to true, and an error
   389  // is returned by f, gRPC checks the error's Temporary() method to decide if it
   390  // should try to reconnect to the network address.
   391  //
   392  // ToDeprecated: use WithContextDialer instead.  Will be supported throughout
   393  // 1.x.
   394  func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
   395  	return WithContextDialer(
   396  		func(ctx context.Context, addr string) (net.Conn, error) {
   397  			if deadline, ok := ctx.Deadline(); ok {
   398  				return f(addr, time.Until(deadline))
   399  			}
   400  			return f(addr, 0)
   401  		})
   402  }
   403  
   404  // WithStatsHandler returns a DialOption that specifies the stats handler for
   405  // all the RPCs and underlying network connections in this ClientConn.
   406  func WithStatsHandler(h stats.Handler) DialOption {
   407  	return newFuncDialOption(func(o *dialOptions) {
   408  		o.copts.StatsHandler = h
   409  	})
   410  }
   411  
   412  // FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on
   413  // non-temporary dial errors. If f is true, and dialer returns a non-temporary
   414  // error, gRPC will fail the connection to the network address and won't try to
   415  // reconnect. The default value of FailOnNonTempDialError is false.
   416  //
   417  // FailOnNonTempDialError only affects the initial dial, and does not do
   418  // anything useful unless you are also using WithBlock().
   419  //
   420  // Experimental
   421  //
   422  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   423  // later release.
   424  func FailOnNonTempDialError(f bool) DialOption {
   425  	return newFuncDialOption(func(o *dialOptions) {
   426  		o.copts.FailOnNonTempDialError = f
   427  	})
   428  }
   429  
   430  // WithUserAgent returns a DialOption that specifies a user agent string for all
   431  // the RPCs.
   432  func WithUserAgent(s string) DialOption {
   433  	return newFuncDialOption(func(o *dialOptions) {
   434  		o.copts.UserAgent = s
   435  	})
   436  }
   437  
   438  // WithKeepaliveParams returns a DialOption that specifies keepalive parameters
   439  // for the client transport.
   440  func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption {
   441  	if kp.Time < internal.KeepaliveMinPingTime {
   442  		logger.Warningf("Adjusting keepalive ping interval to minimum period of %v", internal.KeepaliveMinPingTime)
   443  		kp.Time = internal.KeepaliveMinPingTime
   444  	}
   445  	return newFuncDialOption(func(o *dialOptions) {
   446  		o.copts.KeepaliveParams = kp
   447  	})
   448  }
   449  
   450  // WithUnaryInterceptor returns a DialOption that specifies the interceptor for
   451  // unary RPCs.
   452  func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption {
   453  	return newFuncDialOption(func(o *dialOptions) {
   454  		o.unaryInt = f
   455  	})
   456  }
   457  
   458  // WithChainUnaryInterceptor returns a DialOption that specifies the chained
   459  // interceptor for unary RPCs. The first interceptor will be the outer most,
   460  // while the last interceptor will be the inner most wrapper around the real call.
   461  // All interceptors added by this method will be chained, and the interceptor
   462  // defined by WithUnaryInterceptor will always be prepended to the chain.
   463  func WithChainUnaryInterceptor(interceptors ...UnaryClientInterceptor) DialOption {
   464  	return newFuncDialOption(func(o *dialOptions) {
   465  		o.chainUnaryInts = append(o.chainUnaryInts, interceptors...)
   466  	})
   467  }
   468  
   469  // WithStreamInterceptor returns a DialOption that specifies the interceptor for
   470  // streaming RPCs.
   471  func WithStreamInterceptor(f StreamClientInterceptor) DialOption {
   472  	return newFuncDialOption(func(o *dialOptions) {
   473  		o.streamInt = f
   474  	})
   475  }
   476  
   477  // WithChainStreamInterceptor returns a DialOption that specifies the chained
   478  // interceptor for streaming RPCs. The first interceptor will be the outer most,
   479  // while the last interceptor will be the inner most wrapper around the real call.
   480  // All interceptors added by this method will be chained, and the interceptor
   481  // defined by WithStreamInterceptor will always be prepended to the chain.
   482  func WithChainStreamInterceptor(interceptors ...StreamClientInterceptor) DialOption {
   483  	return newFuncDialOption(func(o *dialOptions) {
   484  		o.chainStreamInts = append(o.chainStreamInts, interceptors...)
   485  	})
   486  }
   487  
   488  // WithAuthority returns a DialOption that specifies the value to be used as the
   489  // :authority pseudo-header and as the server name in authentication handshake.
   490  func WithAuthority(a string) DialOption {
   491  	return newFuncDialOption(func(o *dialOptions) {
   492  		o.authority = a
   493  	})
   494  }
   495  
   496  // WithChannelzParentID returns a DialOption that specifies the channelz ID of
   497  // current ClientConn's parent. This function is used in nested channel creation
   498  // (e.g. grpclb dial).
   499  //
   500  // Experimental
   501  //
   502  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   503  // later release.
   504  func WithChannelzParentID(id int64) DialOption {
   505  	return newFuncDialOption(func(o *dialOptions) {
   506  		o.channelzParentID = id
   507  	})
   508  }
   509  
   510  // WithDisableServiceConfig returns a DialOption that causes gRPC to ignore any
   511  // service config provided by the resolver and provides a hint to the resolver
   512  // to not fetch service configs.
   513  //
   514  // Note that this dial option only disables service config from resolver. If
   515  // default service config is provided, gRPC will use the default service config.
   516  func WithDisableServiceConfig() DialOption {
   517  	return newFuncDialOption(func(o *dialOptions) {
   518  		o.disableServiceConfig = true
   519  	})
   520  }
   521  
   522  // WithDefaultServiceConfig returns a DialOption that configures the default
   523  // service config, which will be used in cases where:
   524  //
   525  // 1. WithDisableServiceConfig is also used, or
   526  //
   527  // 2. The name resolver does not provide a service config or provides an
   528  // invalid service config.
   529  //
   530  // The parameter s is the JSON representation of the default service config.
   531  // For more information about service configs, see:
   532  // https://github.com/grpc/grpc/blob/master/doc/service_config.md
   533  // For a simple example of usage, see:
   534  // examples/features/load_balancing/client/main.go
   535  func WithDefaultServiceConfig(s string) DialOption {
   536  	return newFuncDialOption(func(o *dialOptions) {
   537  		o.defaultServiceConfigRawJSON = &s
   538  	})
   539  }
   540  
   541  // WithDisableRetry returns a DialOption that disables retries, even if the
   542  // service config enables them.  This does not impact transparent retries, which
   543  // will happen automatically if no data is written to the wire or if the RPC is
   544  // unprocessed by the remote server.
   545  //
   546  // Retry support is currently enabled by default, but may be disabled by
   547  // setting the environment variable "GRPC_GO_RETRY" to "off".
   548  //goland:noinspection GoUnusedExportedFunction
   549  func WithDisableRetry() DialOption {
   550  	return newFuncDialOption(func(o *dialOptions) {
   551  		o.disableRetry = true
   552  	})
   553  }
   554  
   555  // WithMaxHeaderListSize returns a DialOption that specifies the maximum
   556  // (uncompressed) size of header list that the client is prepared to accept.
   557  func WithMaxHeaderListSize(s uint32) DialOption {
   558  	return newFuncDialOption(func(o *dialOptions) {
   559  		o.copts.MaxHeaderListSize = &s
   560  	})
   561  }
   562  
   563  // WithDisableHealthCheck disables the LB channel health checking for all
   564  // SubConns of this ClientConn.
   565  //
   566  // Experimental
   567  //
   568  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   569  // later release.
   570  func WithDisableHealthCheck() DialOption {
   571  	return newFuncDialOption(func(o *dialOptions) {
   572  		o.disableHealthCheck = true
   573  	})
   574  }
   575  
   576  // withHealthCheckFunc replaces the default health check function with the
   577  // provided one. It makes tests easier to change the health check function.
   578  //
   579  // For testing purpose only.
   580  func withHealthCheckFunc(f internal.HealthChecker) DialOption {
   581  	return newFuncDialOption(func(o *dialOptions) {
   582  		o.healthCheckFunc = f
   583  	})
   584  }
   585  
   586  func defaultDialOptions() dialOptions {
   587  	return dialOptions{
   588  		healthCheckFunc: internal.HealthCheckFunc,
   589  		copts: transport.ConnectOptions{
   590  			WriteBufferSize: defaultWriteBufSize,
   591  			ReadBufferSize:  defaultReadBufSize,
   592  			UseProxy:        true,
   593  		},
   594  	}
   595  }
   596  
   597  // withGetMinConnectDeadline specifies the function that clientconn uses to
   598  // get minConnectDeadline. This can be used to make connection attempts happen
   599  // faster/slower.
   600  //
   601  // For testing purpose only.
   602  func withMinConnectDeadline(f func() time.Duration) DialOption {
   603  	return newFuncDialOption(func(o *dialOptions) {
   604  		o.minConnectTimeout = f
   605  	})
   606  }
   607  
   608  // WithResolvers allows a list of resolver implementations to be registered
   609  // locally with the ClientConn without needing to be globally registered via
   610  // resolver.Register.  They will be matched against the scheme used for the
   611  // current Dial only, and will take precedence over the global registry.
   612  //
   613  // Experimental
   614  //
   615  // Notice: This API is EXPERIMENTAL and may be changed or removed in a
   616  // later release.
   617  func WithResolvers(rs ...resolver.Builder) DialOption {
   618  	return newFuncDialOption(func(o *dialOptions) {
   619  		o.resolvers = append(o.resolvers, rs...)
   620  	})
   621  }