tearDown starts to tear down the addrConn. Note that tearDown doesn't remove ac from ac.cc.conns, so the addrConn struct will leak. In most cases, call cc.removeAddrConn() instead.
(err error)
| 1691 | // Note that tearDown doesn't remove ac from ac.cc.conns, so the addrConn struct |
| 1692 | // will leak. In most cases, call cc.removeAddrConn() instead. |
| 1693 | func (ac *addrConn) tearDown(err error) { |
| 1694 | ac.mu.Lock() |
| 1695 | if ac.state == connectivity.Shutdown { |
| 1696 | ac.mu.Unlock() |
| 1697 | return |
| 1698 | } |
| 1699 | curTr := ac.transport |
| 1700 | ac.transport = nil |
| 1701 | if ac.disconnectErrorLabel == "" { |
| 1702 | ac.disconnectErrorLabel = "subchannel shutdown" |
| 1703 | } |
| 1704 | // We have to set the state to Shutdown before anything else to prevent races |
| 1705 | // between setting the state and logic that waits on context cancellation / etc. |
| 1706 | ac.updateConnectivityState(connectivity.Shutdown, nil) |
| 1707 | ac.cancel() |
| 1708 | ac.curAddr = resolver.Address{} |
| 1709 | |
| 1710 | channelz.AddTraceEvent(logger, ac.channelz, 0, &channelz.TraceEvent{ |
| 1711 | Desc: "Subchannel deleted", |
| 1712 | Severity: channelz.CtInfo, |
| 1713 | Parent: &channelz.TraceEvent{ |
| 1714 | Desc: fmt.Sprintf("Subchannel(id:%d) deleted", ac.channelz.ID), |
| 1715 | Severity: channelz.CtInfo, |
| 1716 | }, |
| 1717 | }) |
| 1718 | // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add |
| 1719 | // trace reference to the entity being deleted, and thus prevent it from |
| 1720 | // being deleted right away. |
| 1721 | channelz.RemoveEntry(ac.channelz.ID) |
| 1722 | ac.mu.Unlock() |
| 1723 | |
| 1724 | // We have to release the lock before the call to GracefulClose/Close here |
| 1725 | // because both of them call onClose(), which requires locking ac.mu. |
| 1726 | if curTr != nil { |
| 1727 | if err == errConnDrain { |
| 1728 | // Close the transport gracefully when the subConn is being shutdown. |
| 1729 | // |
| 1730 | // GracefulClose() may be executed multiple times if: |
| 1731 | // - multiple GoAway frames are received from the server |
| 1732 | // - there are concurrent name resolver or balancer triggered |
| 1733 | // address removal and GoAway |
| 1734 | curTr.GracefulClose() |
| 1735 | } else { |
| 1736 | // Hard close the transport when the channel is entering idle or is |
| 1737 | // being shutdown. In the case where the channel is being shutdown, |
| 1738 | // closing of transports is also taken care of by cancellation of cc.ctx. |
| 1739 | // But in the case where the channel is entering idle, we need to |
| 1740 | // explicitly close the transports here. Instead of distinguishing |
| 1741 | // between these two cases, it is simpler to close the transport |
| 1742 | // unconditionally here. |
| 1743 | curTr.Close(err) |
| 1744 | } |
| 1745 | } |
| 1746 | } |
| 1747 | |
| 1748 | type retryThrottler struct { |
| 1749 | max float64 |
no test coverage detected