dialoptions.go 23 KB

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