DialContext calls NewClient and then exits idle mode. If WithBlock(true) is used, it calls Connect and WaitForStateChange until either the context expires or the state of the ClientConn is Ready. One subtle difference between NewClient and Dial and DialContext is that the former uses "dns" as the
(ctx context.Context, target string, opts ...DialOption)
| 278 | // |
| 279 | // Deprecated: use NewClient instead. Will be supported throughout 1.x. |
| 280 | func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { |
| 281 | // At the end of this method, we kick the channel out of idle, rather than |
| 282 | // waiting for the first rpc. |
| 283 | // |
| 284 | // WithLocalDNSResolution dial option in `grpc.Dial` ensures that it |
| 285 | // preserves behavior: when default scheme passthrough is used, skip |
| 286 | // hostname resolution, when "dns" is used for resolution, perform |
| 287 | // resolution on the client. |
| 288 | opts = append([]DialOption{withDefaultScheme("passthrough"), WithLocalDNSResolution()}, opts...) |
| 289 | cc, err := NewClient(target, opts...) |
| 290 | if err != nil { |
| 291 | return nil, err |
| 292 | } |
| 293 | |
| 294 | // We start the channel off in idle mode, but kick it out of idle now, |
| 295 | // instead of waiting for the first RPC. This is the legacy behavior of |
| 296 | // Dial. |
| 297 | defer func() { |
| 298 | if err != nil { |
| 299 | cc.Close() |
| 300 | } |
| 301 | }() |
| 302 | |
| 303 | // This creates the name resolver, load balancer, etc. |
| 304 | if err := cc.exitIdleMode(); err != nil { |
| 305 | return nil, fmt.Errorf("failed to exit idle mode: %w", err) |
| 306 | } |
| 307 | cc.idlenessMgr.UnsafeSetNotIdle() |
| 308 | |
| 309 | // Return now for non-blocking dials. |
| 310 | if !cc.dopts.block { |
| 311 | return cc, nil |
| 312 | } |
| 313 | |
| 314 | if cc.dopts.timeout > 0 { |
| 315 | var cancel context.CancelFunc |
| 316 | ctx, cancel = context.WithTimeout(ctx, cc.dopts.timeout) |
| 317 | defer cancel() |
| 318 | } |
| 319 | defer func() { |
| 320 | select { |
| 321 | case <-ctx.Done(): |
| 322 | switch { |
| 323 | case ctx.Err() == err: |
| 324 | conn = nil |
| 325 | case err == nil || !cc.dopts.returnLastError: |
| 326 | conn, err = nil, ctx.Err() |
| 327 | default: |
| 328 | conn, err = nil, fmt.Errorf("%v: %v", ctx.Err(), err) |
| 329 | } |
| 330 | default: |
| 331 | } |
| 332 | }() |
| 333 | |
| 334 | // A blocking dial blocks until the clientConn is ready. |
| 335 | for { |
| 336 | s := cc.GetState() |
| 337 | if s == connectivity.Idle { |