createTransport creates a connection to addr. It returns an error if the address was not successfully connected, or updates ac appropriately with the new transport.
(ctx context.Context, addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time)
| 1488 | // address was not successfully connected, or updates ac appropriately with the |
| 1489 | // new transport. |
| 1490 | func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) error { |
| 1491 | addr.ServerName = ac.cc.getServerName(addr) |
| 1492 | hctx, hcancel := context.WithCancel(ctx) |
| 1493 | |
| 1494 | onClose := func(info transport.GoAwayInfo) { |
| 1495 | ac.mu.Lock() |
| 1496 | defer ac.mu.Unlock() |
| 1497 | // adjust params based on GoAwayReason |
| 1498 | ac.adjustParams(info.Reason) |
| 1499 | if ctx.Err() != nil { |
| 1500 | // Already shut down or connection attempt canceled. tearDown() or |
| 1501 | // updateAddrs() already cleared the transport and canceled hctx |
| 1502 | // via ac.ctx, and we expected this connection to be closed, so do |
| 1503 | // nothing here. |
| 1504 | return |
| 1505 | } |
| 1506 | hcancel() |
| 1507 | if ac.transport == nil { |
| 1508 | // We're still connecting to this address, which could error. Do |
| 1509 | // not update the connectivity state or resolve; these will happen |
| 1510 | // at the end of the tryAllAddrs connection loop in the event of an |
| 1511 | // error. |
| 1512 | return |
| 1513 | } |
| 1514 | ac.transport = nil |
| 1515 | ac.disconnectErrorLabel = disconnectErrorString(info) |
| 1516 | // Refresh the name resolver on any connection loss. |
| 1517 | ac.cc.resolveNow(resolver.ResolveNowOptions{}) |
| 1518 | // Always go idle and wait for the LB policy to initiate a new |
| 1519 | // connection attempt. |
| 1520 | ac.updateConnectivityState(connectivity.Idle, nil) |
| 1521 | } |
| 1522 | |
| 1523 | connectCtx, cancel := context.WithDeadline(ctx, connectDeadline) |
| 1524 | defer cancel() |
| 1525 | copts.ChannelzParent = ac.channelz |
| 1526 | |
| 1527 | newTr, err := transport.NewHTTP2Client(connectCtx, ac.cc.ctx, addr, copts, onClose) |
| 1528 | if err != nil { |
| 1529 | if logger.V(2) { |
| 1530 | logger.Infof("Creating new client transport to %q: %v", addr, err) |
| 1531 | } |
| 1532 | // newTr is either nil, or closed. |
| 1533 | hcancel() |
| 1534 | channelz.Warningf(logger, ac.channelz, "grpc: addrConn.createTransport failed to connect to %s. Err: %v", addr, err) |
| 1535 | return err |
| 1536 | } |
| 1537 | |
| 1538 | ac.mu.Lock() |
| 1539 | if ctx.Err() != nil { |
| 1540 | // This can happen if the subConn was removed while in `Connecting` |
| 1541 | // state. tearDown() would have set the state to `Shutdown`, but |
| 1542 | // would not have closed the transport since ac.transport would not |
| 1543 | // have been set at that point. |
| 1544 | |
| 1545 | // We unlock ac.mu because newTr.Close() calls onClose() |
| 1546 | // inline, which requires locking ac.mu. |
| 1547 | ac.mu.Unlock() |
no test coverage detected