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