google.golang.org/grpc@v1.62.1/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 "net" 24 "time" 25 26 "google.golang.org/grpc/backoff" 27 "google.golang.org/grpc/channelz" 28 "google.golang.org/grpc/credentials" 29 "google.golang.org/grpc/credentials/insecure" 30 "google.golang.org/grpc/internal" 31 internalbackoff "google.golang.org/grpc/internal/backoff" 32 "google.golang.org/grpc/internal/binarylog" 33 "google.golang.org/grpc/internal/transport" 34 "google.golang.org/grpc/keepalive" 35 "google.golang.org/grpc/resolver" 36 "google.golang.org/grpc/stats" 37 ) 38 39 func init() { 40 internal.AddGlobalDialOptions = func(opt ...DialOption) { 41 globalDialOptions = append(globalDialOptions, opt...) 42 } 43 internal.ClearGlobalDialOptions = func() { 44 globalDialOptions = nil 45 } 46 internal.WithBinaryLogger = withBinaryLogger 47 internal.JoinDialOptions = newJoinDialOption 48 internal.DisableGlobalDialOptions = newDisableGlobalDialOptions 49 internal.WithRecvBufferPool = withRecvBufferPool 50 } 51 52 // dialOptions configure a Dial call. dialOptions are set by the DialOption 53 // values passed to Dial. 54 type dialOptions struct { 55 unaryInt UnaryClientInterceptor 56 streamInt StreamClientInterceptor 57 58 chainUnaryInts []UnaryClientInterceptor 59 chainStreamInts []StreamClientInterceptor 60 61 cp Compressor 62 dc Decompressor 63 bs internalbackoff.Strategy 64 block bool 65 returnLastError bool 66 timeout time.Duration 67 authority string 68 binaryLogger binarylog.Logger 69 copts transport.ConnectOptions 70 callOptions []CallOption 71 channelzParentID *channelz.Identifier 72 disableServiceConfig bool 73 disableRetry bool 74 disableHealthCheck bool 75 healthCheckFunc internal.HealthChecker 76 minConnectTimeout func() time.Duration 77 defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON. 78 defaultServiceConfigRawJSON *string 79 resolvers []resolver.Builder 80 idleTimeout time.Duration 81 recvBufferPool SharedBufferPool 82 } 83 84 // DialOption configures how we set up the connection. 85 type DialOption interface { 86 apply(*dialOptions) 87 } 88 89 var globalDialOptions []DialOption 90 91 // EmptyDialOption does not alter the dial configuration. It can be embedded in 92 // another structure to build custom dial options. 93 // 94 // # Experimental 95 // 96 // Notice: This type is EXPERIMENTAL and may be changed or removed in a 97 // later release. 98 type EmptyDialOption struct{} 99 100 func (EmptyDialOption) apply(*dialOptions) {} 101 102 type disableGlobalDialOptions struct{} 103 104 func (disableGlobalDialOptions) apply(*dialOptions) {} 105 106 // newDisableGlobalDialOptions returns a DialOption that prevents the ClientConn 107 // from applying the global DialOptions (set via AddGlobalDialOptions). 108 func newDisableGlobalDialOptions() DialOption { 109 return &disableGlobalDialOptions{} 110 } 111 112 // funcDialOption wraps a function that modifies dialOptions into an 113 // implementation of the DialOption interface. 114 type funcDialOption struct { 115 f func(*dialOptions) 116 } 117 118 func (fdo *funcDialOption) apply(do *dialOptions) { 119 fdo.f(do) 120 } 121 122 func newFuncDialOption(f func(*dialOptions)) *funcDialOption { 123 return &funcDialOption{ 124 f: f, 125 } 126 } 127 128 type joinDialOption struct { 129 opts []DialOption 130 } 131 132 func (jdo *joinDialOption) apply(do *dialOptions) { 133 for _, opt := range jdo.opts { 134 opt.apply(do) 135 } 136 } 137 138 func newJoinDialOption(opts ...DialOption) DialOption { 139 return &joinDialOption{opts: opts} 140 } 141 142 // WithSharedWriteBuffer allows reusing per-connection transport write buffer. 143 // If this option is set to true every connection will release the buffer after 144 // flushing the data on the wire. 145 // 146 // # Experimental 147 // 148 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 149 // later release. 150 func WithSharedWriteBuffer(val bool) DialOption { 151 return newFuncDialOption(func(o *dialOptions) { 152 o.copts.SharedWriteBuffer = val 153 }) 154 } 155 156 // WithWriteBufferSize determines how much data can be batched before doing a 157 // write on the wire. The corresponding memory allocation for this buffer will 158 // be twice the size to keep syscalls low. The default value for this buffer is 159 // 32KB. 160 // 161 // Zero or negative values will disable the write buffer such that each write 162 // will be on underlying connection. Note: A Send call may not directly 163 // translate to a write. 164 func WithWriteBufferSize(s int) DialOption { 165 return newFuncDialOption(func(o *dialOptions) { 166 o.copts.WriteBufferSize = s 167 }) 168 } 169 170 // WithReadBufferSize lets you set the size of read buffer, this determines how 171 // much data can be read at most for each read syscall. 172 // 173 // The default value for this buffer is 32KB. Zero or negative values will 174 // disable read buffer for a connection so data framer can access the 175 // underlying conn directly. 176 func WithReadBufferSize(s int) DialOption { 177 return newFuncDialOption(func(o *dialOptions) { 178 o.copts.ReadBufferSize = s 179 }) 180 } 181 182 // WithInitialWindowSize returns a DialOption which sets the value for initial 183 // window size on a stream. The lower bound for window size is 64K and any value 184 // smaller than that will be ignored. 185 func WithInitialWindowSize(s int32) DialOption { 186 return newFuncDialOption(func(o *dialOptions) { 187 o.copts.InitialWindowSize = s 188 }) 189 } 190 191 // WithInitialConnWindowSize returns a DialOption which sets the value for 192 // initial window size on a connection. The lower bound for window size is 64K 193 // and any value smaller than that will be ignored. 194 func WithInitialConnWindowSize(s int32) DialOption { 195 return newFuncDialOption(func(o *dialOptions) { 196 o.copts.InitialConnWindowSize = s 197 }) 198 } 199 200 // WithMaxMsgSize returns a DialOption which sets the maximum message size the 201 // client can receive. 202 // 203 // Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead. Will 204 // be supported throughout 1.x. 205 func WithMaxMsgSize(s int) DialOption { 206 return WithDefaultCallOptions(MaxCallRecvMsgSize(s)) 207 } 208 209 // WithDefaultCallOptions returns a DialOption which sets the default 210 // CallOptions for calls over the connection. 211 func WithDefaultCallOptions(cos ...CallOption) DialOption { 212 return newFuncDialOption(func(o *dialOptions) { 213 o.callOptions = append(o.callOptions, cos...) 214 }) 215 } 216 217 // WithCodec returns a DialOption which sets a codec for message marshaling and 218 // unmarshaling. 219 // 220 // Deprecated: use WithDefaultCallOptions(ForceCodec(_)) instead. Will be 221 // supported throughout 1.x. 222 func WithCodec(c Codec) DialOption { 223 return WithDefaultCallOptions(CallCustomCodec(c)) 224 } 225 226 // WithCompressor returns a DialOption which sets a Compressor to use for 227 // message compression. It has lower priority than the compressor set by the 228 // UseCompressor CallOption. 229 // 230 // Deprecated: use UseCompressor instead. Will be supported throughout 1.x. 231 func WithCompressor(cp Compressor) DialOption { 232 return newFuncDialOption(func(o *dialOptions) { 233 o.cp = cp 234 }) 235 } 236 237 // WithDecompressor returns a DialOption which sets a Decompressor to use for 238 // incoming message decompression. If incoming response messages are encoded 239 // using the decompressor's Type(), it will be used. Otherwise, the message 240 // encoding will be used to look up the compressor registered via 241 // encoding.RegisterCompressor, which will then be used to decompress the 242 // message. If no compressor is registered for the encoding, an Unimplemented 243 // status error will be returned. 244 // 245 // Deprecated: use encoding.RegisterCompressor instead. Will be supported 246 // throughout 1.x. 247 func WithDecompressor(dc Decompressor) DialOption { 248 return newFuncDialOption(func(o *dialOptions) { 249 o.dc = dc 250 }) 251 } 252 253 // WithConnectParams configures the ClientConn to use the provided ConnectParams 254 // for creating and maintaining connections to servers. 255 // 256 // The backoff configuration specified as part of the ConnectParams overrides 257 // all defaults specified in 258 // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. Consider 259 // using the backoff.DefaultConfig as a base, in cases where you want to 260 // override only a subset of the backoff configuration. 261 func WithConnectParams(p ConnectParams) DialOption { 262 return newFuncDialOption(func(o *dialOptions) { 263 o.bs = internalbackoff.Exponential{Config: p.Backoff} 264 o.minConnectTimeout = func() time.Duration { 265 return p.MinConnectTimeout 266 } 267 }) 268 } 269 270 // WithBackoffMaxDelay configures the dialer to use the provided maximum delay 271 // when backing off after failed connection attempts. 272 // 273 // Deprecated: use WithConnectParams instead. Will be supported throughout 1.x. 274 func WithBackoffMaxDelay(md time.Duration) DialOption { 275 return WithBackoffConfig(BackoffConfig{MaxDelay: md}) 276 } 277 278 // WithBackoffConfig configures the dialer to use the provided backoff 279 // parameters after connection failures. 280 // 281 // Deprecated: use WithConnectParams instead. Will be supported throughout 1.x. 282 func WithBackoffConfig(b BackoffConfig) DialOption { 283 bc := backoff.DefaultConfig 284 bc.MaxDelay = b.MaxDelay 285 return withBackoff(internalbackoff.Exponential{Config: bc}) 286 } 287 288 // withBackoff sets the backoff strategy used for connectRetryNum after a failed 289 // connection attempt. 290 // 291 // This can be exported if arbitrary backoff strategies are allowed by gRPC. 292 func withBackoff(bs internalbackoff.Strategy) DialOption { 293 return newFuncDialOption(func(o *dialOptions) { 294 o.bs = bs 295 }) 296 } 297 298 // WithBlock returns a DialOption which makes callers of Dial block until the 299 // underlying connection is up. Without this, Dial returns immediately and 300 // connecting the server happens in background. 301 // 302 // Use of this feature is not recommended. For more information, please see: 303 // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md 304 func WithBlock() DialOption { 305 return newFuncDialOption(func(o *dialOptions) { 306 o.block = true 307 }) 308 } 309 310 // WithReturnConnectionError returns a DialOption which makes the client connection 311 // return a string containing both the last connection error that occurred and 312 // the context.DeadlineExceeded error. 313 // Implies WithBlock() 314 // 315 // Use of this feature is not recommended. For more information, please see: 316 // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md 317 // 318 // # Experimental 319 // 320 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 321 // later release. 322 func WithReturnConnectionError() DialOption { 323 return newFuncDialOption(func(o *dialOptions) { 324 o.block = true 325 o.returnLastError = true 326 }) 327 } 328 329 // WithInsecure returns a DialOption which disables transport security for this 330 // ClientConn. Under the hood, it uses insecure.NewCredentials(). 331 // 332 // Note that using this DialOption with per-RPC credentials (through 333 // WithCredentialsBundle or WithPerRPCCredentials) which require transport 334 // security is incompatible and will cause grpc.Dial() to fail. 335 // 336 // Deprecated: use WithTransportCredentials and insecure.NewCredentials() 337 // instead. Will be supported throughout 1.x. 338 func WithInsecure() DialOption { 339 return newFuncDialOption(func(o *dialOptions) { 340 o.copts.TransportCredentials = insecure.NewCredentials() 341 }) 342 } 343 344 // WithNoProxy returns a DialOption which disables the use of proxies for this 345 // ClientConn. This is ignored if WithDialer or WithContextDialer are used. 346 // 347 // # Experimental 348 // 349 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 350 // later release. 351 func WithNoProxy() DialOption { 352 return newFuncDialOption(func(o *dialOptions) { 353 o.copts.UseProxy = false 354 }) 355 } 356 357 // WithTransportCredentials returns a DialOption which configures a connection 358 // level security credentials (e.g., TLS/SSL). This should not be used together 359 // with WithCredentialsBundle. 360 func WithTransportCredentials(creds credentials.TransportCredentials) DialOption { 361 return newFuncDialOption(func(o *dialOptions) { 362 o.copts.TransportCredentials = creds 363 }) 364 } 365 366 // WithPerRPCCredentials returns a DialOption which sets credentials and places 367 // auth state on each outbound RPC. 368 func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption { 369 return newFuncDialOption(func(o *dialOptions) { 370 o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds) 371 }) 372 } 373 374 // WithCredentialsBundle returns a DialOption to set a credentials bundle for 375 // the ClientConn.WithCreds. This should not be used together with 376 // WithTransportCredentials. 377 // 378 // # Experimental 379 // 380 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 381 // later release. 382 func WithCredentialsBundle(b credentials.Bundle) DialOption { 383 return newFuncDialOption(func(o *dialOptions) { 384 o.copts.CredsBundle = b 385 }) 386 } 387 388 // WithTimeout returns a DialOption that configures a timeout for dialing a 389 // ClientConn initially. This is valid if and only if WithBlock() is present. 390 // 391 // Deprecated: use DialContext instead of Dial and context.WithTimeout 392 // instead. Will be supported throughout 1.x. 393 func WithTimeout(d time.Duration) DialOption { 394 return newFuncDialOption(func(o *dialOptions) { 395 o.timeout = d 396 }) 397 } 398 399 // WithContextDialer returns a DialOption that sets a dialer to create 400 // connections. If FailOnNonTempDialError() is set to true, and an error is 401 // returned by f, gRPC checks the error's Temporary() method to decide if it 402 // should try to reconnect to the network address. 403 // 404 // Note: All supported releases of Go (as of December 2023) override the OS 405 // defaults for TCP keepalive time and interval to 15s. To enable TCP keepalive 406 // with OS defaults for keepalive time and interval, use a net.Dialer that sets 407 // the KeepAlive field to a negative value, and sets the SO_KEEPALIVE socket 408 // option to true from the Control field. For a concrete example of how to do 409 // this, see internal.NetDialerWithTCPKeepalive(). 410 // 411 // For more information, please see [issue 23459] in the Go github repo. 412 // 413 // [issue 23459]: https://github.com/golang/go/issues/23459 414 func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { 415 return newFuncDialOption(func(o *dialOptions) { 416 o.copts.Dialer = f 417 }) 418 } 419 420 func init() { 421 internal.WithHealthCheckFunc = withHealthCheckFunc 422 } 423 424 // WithDialer returns a DialOption that specifies a function to use for dialing 425 // network addresses. If FailOnNonTempDialError() is set to true, and an error 426 // is returned by f, gRPC checks the error's Temporary() method to decide if it 427 // should try to reconnect to the network address. 428 // 429 // Deprecated: use WithContextDialer instead. Will be supported throughout 430 // 1.x. 431 func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { 432 return WithContextDialer( 433 func(ctx context.Context, addr string) (net.Conn, error) { 434 if deadline, ok := ctx.Deadline(); ok { 435 return f(addr, time.Until(deadline)) 436 } 437 return f(addr, 0) 438 }) 439 } 440 441 // WithStatsHandler returns a DialOption that specifies the stats handler for 442 // all the RPCs and underlying network connections in this ClientConn. 443 func WithStatsHandler(h stats.Handler) DialOption { 444 return newFuncDialOption(func(o *dialOptions) { 445 if h == nil { 446 logger.Error("ignoring nil parameter in grpc.WithStatsHandler ClientOption") 447 // Do not allow a nil stats handler, which would otherwise cause 448 // panics. 449 return 450 } 451 o.copts.StatsHandlers = append(o.copts.StatsHandlers, h) 452 }) 453 } 454 455 // withBinaryLogger returns a DialOption that specifies the binary logger for 456 // this ClientConn. 457 func withBinaryLogger(bl binarylog.Logger) DialOption { 458 return newFuncDialOption(func(o *dialOptions) { 459 o.binaryLogger = bl 460 }) 461 } 462 463 // FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on 464 // non-temporary dial errors. If f is true, and dialer returns a non-temporary 465 // error, gRPC will fail the connection to the network address and won't try to 466 // reconnect. The default value of FailOnNonTempDialError is false. 467 // 468 // FailOnNonTempDialError only affects the initial dial, and does not do 469 // anything useful unless you are also using WithBlock(). 470 // 471 // Use of this feature is not recommended. For more information, please see: 472 // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md 473 // 474 // # Experimental 475 // 476 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 477 // later release. 478 func FailOnNonTempDialError(f bool) DialOption { 479 return newFuncDialOption(func(o *dialOptions) { 480 o.copts.FailOnNonTempDialError = f 481 }) 482 } 483 484 // WithUserAgent returns a DialOption that specifies a user agent string for all 485 // the RPCs. 486 func WithUserAgent(s string) DialOption { 487 return newFuncDialOption(func(o *dialOptions) { 488 o.copts.UserAgent = s + " " + grpcUA 489 }) 490 } 491 492 // WithKeepaliveParams returns a DialOption that specifies keepalive parameters 493 // for the client transport. 494 func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption { 495 if kp.Time < internal.KeepaliveMinPingTime { 496 logger.Warningf("Adjusting keepalive ping interval to minimum period of %v", internal.KeepaliveMinPingTime) 497 kp.Time = internal.KeepaliveMinPingTime 498 } 499 return newFuncDialOption(func(o *dialOptions) { 500 o.copts.KeepaliveParams = kp 501 }) 502 } 503 504 // WithUnaryInterceptor returns a DialOption that specifies the interceptor for 505 // unary RPCs. 506 func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption { 507 return newFuncDialOption(func(o *dialOptions) { 508 o.unaryInt = f 509 }) 510 } 511 512 // WithChainUnaryInterceptor returns a DialOption that specifies the chained 513 // interceptor for unary RPCs. The first interceptor will be the outer most, 514 // while the last interceptor will be the inner most wrapper around the real call. 515 // All interceptors added by this method will be chained, and the interceptor 516 // defined by WithUnaryInterceptor will always be prepended to the chain. 517 func WithChainUnaryInterceptor(interceptors ...UnaryClientInterceptor) DialOption { 518 return newFuncDialOption(func(o *dialOptions) { 519 o.chainUnaryInts = append(o.chainUnaryInts, interceptors...) 520 }) 521 } 522 523 // WithStreamInterceptor returns a DialOption that specifies the interceptor for 524 // streaming RPCs. 525 func WithStreamInterceptor(f StreamClientInterceptor) DialOption { 526 return newFuncDialOption(func(o *dialOptions) { 527 o.streamInt = f 528 }) 529 } 530 531 // WithChainStreamInterceptor returns a DialOption that specifies the chained 532 // interceptor for streaming RPCs. The first interceptor will be the outer most, 533 // while the last interceptor will be the inner most wrapper around the real call. 534 // All interceptors added by this method will be chained, and the interceptor 535 // defined by WithStreamInterceptor will always be prepended to the chain. 536 func WithChainStreamInterceptor(interceptors ...StreamClientInterceptor) DialOption { 537 return newFuncDialOption(func(o *dialOptions) { 538 o.chainStreamInts = append(o.chainStreamInts, interceptors...) 539 }) 540 } 541 542 // WithAuthority returns a DialOption that specifies the value to be used as the 543 // :authority pseudo-header and as the server name in authentication handshake. 544 func WithAuthority(a string) DialOption { 545 return newFuncDialOption(func(o *dialOptions) { 546 o.authority = a 547 }) 548 } 549 550 // WithChannelzParentID returns a DialOption that specifies the channelz ID of 551 // current ClientConn's parent. This function is used in nested channel creation 552 // (e.g. grpclb dial). 553 // 554 // # Experimental 555 // 556 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 557 // later release. 558 func WithChannelzParentID(id *channelz.Identifier) DialOption { 559 return newFuncDialOption(func(o *dialOptions) { 560 o.channelzParentID = id 561 }) 562 } 563 564 // WithDisableServiceConfig returns a DialOption that causes gRPC to ignore any 565 // service config provided by the resolver and provides a hint to the resolver 566 // to not fetch service configs. 567 // 568 // Note that this dial option only disables service config from resolver. If 569 // default service config is provided, gRPC will use the default service config. 570 func WithDisableServiceConfig() DialOption { 571 return newFuncDialOption(func(o *dialOptions) { 572 o.disableServiceConfig = true 573 }) 574 } 575 576 // WithDefaultServiceConfig returns a DialOption that configures the default 577 // service config, which will be used in cases where: 578 // 579 // 1. WithDisableServiceConfig is also used, or 580 // 581 // 2. The name resolver does not provide a service config or provides an 582 // invalid service config. 583 // 584 // The parameter s is the JSON representation of the default service config. 585 // For more information about service configs, see: 586 // https://github.com/grpc/grpc/blob/master/doc/service_config.md 587 // For a simple example of usage, see: 588 // examples/features/load_balancing/client/main.go 589 func WithDefaultServiceConfig(s string) DialOption { 590 return newFuncDialOption(func(o *dialOptions) { 591 o.defaultServiceConfigRawJSON = &s 592 }) 593 } 594 595 // WithDisableRetry returns a DialOption that disables retries, even if the 596 // service config enables them. This does not impact transparent retries, which 597 // will happen automatically if no data is written to the wire or if the RPC is 598 // unprocessed by the remote server. 599 func WithDisableRetry() DialOption { 600 return newFuncDialOption(func(o *dialOptions) { 601 o.disableRetry = true 602 }) 603 } 604 605 // WithMaxHeaderListSize returns a DialOption that specifies the maximum 606 // (uncompressed) size of header list that the client is prepared to accept. 607 func WithMaxHeaderListSize(s uint32) DialOption { 608 return newFuncDialOption(func(o *dialOptions) { 609 o.copts.MaxHeaderListSize = &s 610 }) 611 } 612 613 // WithDisableHealthCheck disables the LB channel health checking for all 614 // SubConns of this ClientConn. 615 // 616 // # Experimental 617 // 618 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 619 // later release. 620 func WithDisableHealthCheck() DialOption { 621 return newFuncDialOption(func(o *dialOptions) { 622 o.disableHealthCheck = true 623 }) 624 } 625 626 // withHealthCheckFunc replaces the default health check function with the 627 // provided one. It makes tests easier to change the health check function. 628 // 629 // For testing purpose only. 630 func withHealthCheckFunc(f internal.HealthChecker) DialOption { 631 return newFuncDialOption(func(o *dialOptions) { 632 o.healthCheckFunc = f 633 }) 634 } 635 636 func defaultDialOptions() dialOptions { 637 return dialOptions{ 638 copts: transport.ConnectOptions{ 639 ReadBufferSize: defaultReadBufSize, 640 WriteBufferSize: defaultWriteBufSize, 641 UseProxy: true, 642 UserAgent: grpcUA, 643 }, 644 bs: internalbackoff.DefaultExponential, 645 healthCheckFunc: internal.HealthCheckFunc, 646 idleTimeout: 30 * time.Minute, 647 recvBufferPool: nopBufferPool{}, 648 } 649 } 650 651 // withGetMinConnectDeadline specifies the function that clientconn uses to 652 // get minConnectDeadline. This can be used to make connection attempts happen 653 // faster/slower. 654 // 655 // For testing purpose only. 656 func withMinConnectDeadline(f func() time.Duration) DialOption { 657 return newFuncDialOption(func(o *dialOptions) { 658 o.minConnectTimeout = f 659 }) 660 } 661 662 // WithResolvers allows a list of resolver implementations to be registered 663 // locally with the ClientConn without needing to be globally registered via 664 // resolver.Register. They will be matched against the scheme used for the 665 // current Dial only, and will take precedence over the global registry. 666 // 667 // # Experimental 668 // 669 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 670 // later release. 671 func WithResolvers(rs ...resolver.Builder) DialOption { 672 return newFuncDialOption(func(o *dialOptions) { 673 o.resolvers = append(o.resolvers, rs...) 674 }) 675 } 676 677 // WithIdleTimeout returns a DialOption that configures an idle timeout for the 678 // channel. If the channel is idle for the configured timeout, i.e there are no 679 // ongoing RPCs and no new RPCs are initiated, the channel will enter idle mode 680 // and as a result the name resolver and load balancer will be shut down. The 681 // channel will exit idle mode when the Connect() method is called or when an 682 // RPC is initiated. 683 // 684 // A default timeout of 30 minutes will be used if this dial option is not set 685 // at dial time and idleness can be disabled by passing a timeout of zero. 686 // 687 // # Experimental 688 // 689 // Notice: This API is EXPERIMENTAL and may be changed or removed in a 690 // later release. 691 func WithIdleTimeout(d time.Duration) DialOption { 692 return newFuncDialOption(func(o *dialOptions) { 693 o.idleTimeout = d 694 }) 695 } 696 697 // WithRecvBufferPool returns a DialOption that configures the ClientConn 698 // to use the provided shared buffer pool for parsing incoming messages. Depending 699 // on the application's workload, this could result in reduced memory allocation. 700 // 701 // If you are unsure about how to implement a memory pool but want to utilize one, 702 // begin with grpc.NewSharedBufferPool. 703 // 704 // Note: The shared buffer pool feature will not be active if any of the following 705 // options are used: WithStatsHandler, EnableTracing, or binary logging. In such 706 // cases, the shared buffer pool will be ignored. 707 // 708 // Deprecated: use experimental.WithRecvBufferPool instead. Will be deleted in 709 // v1.60.0 or later. 710 func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption { 711 return withRecvBufferPool(bufferPool) 712 } 713 714 func withRecvBufferPool(bufferPool SharedBufferPool) DialOption { 715 return newFuncDialOption(func(o *dialOptions) { 716 o.recvBufferPool = bufferPool 717 }) 718 }