Repository: grpc/grpc-go
File: internal/resolver/delegatingresolver/delegatingresolver.go (Go)

Code before:
		if networkType, _ := networkTypeFromAddr(addr); networkType == "tcp" {
			return true
		}
	}
	for _, endpoint := range state.Endpoints {
		for _, addr := range endpoint.Addresses {
			if networktype, _ := networkTypeFromAddr(addr); networktype == "tcp" {
				return true
			}
		}
	}
	return false
}

// updateClientConnStateLocked creates a list of combined addresses by
// pairing each proxy address with every target address. For each pair, it
// generates a new [resolver.Address] using the proxy address, and adding the
// target address as the attribute along with user info. It returns nil if
// either resolver has not sent update even once and returns the error from
// ClientConn update once both resolvers have sent update atleast once.
func (r *delegatingResolver) updateClientConnStateLocked() error {
	if r.targetResolverState == nil {
		return nil
	}

	curState := *r.targetResolverState

	// If no addresses returned by resolver have network type as tcp , do not wait for proxy update.
	if !tcpAddressPresent(r.targetResolverState) {
		return r.cc.UpdateState(curState)
	}

	if r.proxyAddrs == nil {
		return nil
	}

	// If multiple resolved proxy addresses are present, we send only the
	// unresolved proxy host and let net.Dial handle the proxy host name
	// resolution when creating the transport. Sending all resolved addresses
	// would increase the number of addresses passed to the ClientConn and
	// subsequently to load balancing (LB) policies like Round Robin, leading
	// to additional TCP connections. However, if there's only one resolved
	// proxy address, we send it directly, as it doesn't affect the address
	// count returned by the target resolver and the address count sent to the
	// ClientConn.
	var proxyAddr resolver.Address
	if len(r.proxyAddrs) == 1 {
		proxyAddr = r.proxyAddrs[0]
	} else {
		proxyAddr = resolver.Address{Addr: r.proxyURL.Host}
	}

Review comment (suggestion):
Even though we have this local variable `curState`, I see that the code (both existing and newly added) also uses `r.targetResolverState` in multiple places. Can we make it consistent and use only one of them.

Code after:
	// proxy address, we send it directly, as it doesn't affect the address
	// count returned by the target resolver and the address count sent to the
	// ClientConn.
	var proxyAddr resolver.Address
	if len(r.proxyAddrs) == 1 {
		proxyAddr = r.proxyAddrs[0]
	} else {
		proxyAddr = resolver.Address{Addr: r.proxyURL.Host}
	}
	var addresses []resolver.Address
	for _, targetAddr := range (*r.targetResolverState).Addresses {
		// Avoid proxy when network is not tcp.
		if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" {
			addresses = append(addresses, targetAddr)
			continue
		}
		addresses = append(addresses, proxyattributes.Set(proxyAddr, proxyattributes.Options{
			User:        r.proxyURL.User,
			ConnectAddr: targetAddr.Addr,
		}))
	}

	// For each target endpoint, construct a new [resolver.Endpoint] that
	// includes all addresses from all proxy endpoints and the addresses from
	// that target endpoint, preserving the number of target endpoints.
	var endpoints []resolver.Endpoint
	for _, endpt := range (*r.targetResolverState).Endpoints {
		var addrs []resolver.Address
		for _, targetAddr := range endpt.Addresses {
			// Avoid proxy when network is not tcp.
			if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" {
				addrs = append(addrs, targetAddr)
				continue
			}
			for _, proxyAddr := range r.proxyAddrs {
				addrs = append(addrs, proxyattributes.Set(proxyAddr, proxyattributes.Options{
					User:        r.proxyURL.User,
					ConnectAddr: targetAddr.Addr,
				}))
			}
		}
		endpoints = append(endpoints, resolver.Endpoint{Addresses: addrs})
	}
	// Use the targetResolverState for its service config and attributes
	// contents. The state update is only sent after both the target and proxy
	// resolvers have sent their updates, and curState has been updated with the
	// combined addresses.
	curState := *r.targetResolverState
	curState.Addresses = addresses
	curState.Endpoints = endpoints
	return r.cc.UpdateState(curState)