6767 errConnDrain = errors .New ("grpc: the connection is drained" )
6868 // errConnClosing indicates that the connection is closing.
6969 errConnClosing = errors .New ("grpc: the connection is closing" )
70- // errConnIdling indicates the the connection is being closed as the channel
70+ // errConnIdling indicates the connection is being closed as the channel
7171 // is moving to an idle mode due to inactivity.
7272 errConnIdling = errors .New ("grpc: the connection is closing due to channel idleness" )
7373 // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default
@@ -101,11 +101,6 @@ const (
101101 defaultReadBufSize = 32 * 1024
102102)
103103
104- // Dial creates a client connection to the given target.
105- func Dial (target string , opts ... DialOption ) (* ClientConn , error ) {
106- return DialContext (context .Background (), target , opts ... )
107- }
108-
109104type defaultConfigSelector struct {
110105 sc * ServiceConfig
111106}
@@ -117,8 +112,18 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires
117112 }, nil
118113}
119114
120- // newClient returns a new client in idle mode.
121- func newClient (target string , opts ... DialOption ) (conn * ClientConn , err error ) {
115+ // NewClient creates a new gRPC "channel" for the target URI provided. No I/O
116+ // is performed. Use of the ClientConn for RPCs will automatically cause it to
117+ // connect. Connect may be used to manually create a connection, but for most
118+ // users this is unnecessary.
119+ //
120+ // The target name syntax is defined in
121+ // https://github.com/grpc/grpc/blob/master/doc/naming.md. e.g. to use dns
122+ // resolver, a "dns:///" prefix should be applied to the target.
123+ //
124+ // The DialOptions returned by WithBlock, WithTimeout, and
125+ // WithReturnConnectionError are ignored by this function.
126+ func NewClient (target string , opts ... DialOption ) (conn * ClientConn , err error ) {
122127 cc := & ClientConn {
123128 target : target ,
124129 conns : make (map [* addrConn ]struct {}),
@@ -190,39 +195,36 @@ func newClient(target string, opts ...DialOption) (conn *ClientConn, err error)
190195 return cc , nil
191196}
192197
193- // DialContext creates a client connection to the given target. By default, it's
194- // a non-blocking dial (the function won't wait for connections to be
195- // established, and connecting happens in the background). To make it a blocking
196- // dial, use WithBlock() dial option.
198+ // Dial calls DialContext(context.Background(), target, opts...).
197199//
198- // In the non-blocking case, the ctx does not act against the connection. It
199- // only controls the setup steps.
200+ // Deprecated: use NewClient instead. Will be supported throughout 1.x.
201+ func Dial (target string , opts ... DialOption ) (* ClientConn , error ) {
202+ return DialContext (context .Background (), target , opts ... )
203+ }
204+
205+ // DialContext calls NewClient and then exits idle mode. If WithBlock(true) is
206+ // used, it calls Connect and WaitForStateChange until either the context
207+ // expires or the state of the ClientConn is Ready.
200208//
201- // In the blocking case, ctx can be used to cancel or expire the pending
202- // connection. Once this function returns, the cancellation and expiration of
203- // ctx will be noop. Users should call ClientConn.Close to terminate all the
204- // pending operations after this function returns.
209+ // One subtle difference between NewClient and Dial and DialContext is that the
210+ // former uses "dns" as the default name resolver, while the latter use
211+ // "passthrough" for backward compatibility. This distinction should not matter
212+ // to most users, but could matter to legacy users that specify a custom dialer
213+ // and expect it to receive the target string directly.
205214//
206- // The target name syntax is defined in
207- // https://github.com/grpc/grpc/blob/master/doc/naming.md.
208- // e.g. to use dns resolver, a "dns:///" prefix should be applied to the target.
215+ // Deprecated: use NewClient instead. Will be supported throughout 1.x.
209216func DialContext (ctx context.Context , target string , opts ... DialOption ) (conn * ClientConn , err error ) {
210- cc , err := newClient (target , opts ... )
217+ // At the end of this method, we kick the channel out of idle, rather than
218+ // waiting for the first rpc.
219+ opts = append ([]DialOption {withDefaultScheme ("passthrough" )}, opts ... )
220+ cc , err := NewClient (target , opts ... )
211221 if err != nil {
212222 return nil , err
213223 }
214224
215225 // We start the channel off in idle mode, but kick it out of idle now,
216- // instead of waiting for the first RPC. Other gRPC implementations do wait
217- // for the first RPC to kick the channel out of idle. But doing so would be
218- // a major behavior change for our users who are used to seeing the channel
219- // active after Dial.
220- //
221- // Taking this approach of kicking it out of idle at the end of this method
222- // allows us to share the code between channel creation and exiting idle
223- // mode. This will also make it easy for us to switch to starting the
224- // channel off in idle, i.e. by making newClient exported.
225-
226+ // instead of waiting for the first RPC. This is the legacy behavior of
227+ // Dial.
226228 defer func () {
227229 if err != nil {
228230 cc .Close ()
@@ -706,15 +708,15 @@ func init() {
706708 }
707709}
708710
709- func (cc * ClientConn ) maybeApplyDefaultServiceConfig (addrs []resolver. Address ) {
711+ func (cc * ClientConn ) maybeApplyDefaultServiceConfig () {
710712 if cc .sc != nil {
711- cc .applyServiceConfigAndBalancer (cc .sc , nil , addrs )
713+ cc .applyServiceConfigAndBalancer (cc .sc , nil )
712714 return
713715 }
714716 if cc .dopts .defaultServiceConfig != nil {
715- cc .applyServiceConfigAndBalancer (cc .dopts .defaultServiceConfig , & defaultConfigSelector {cc .dopts .defaultServiceConfig }, addrs )
717+ cc .applyServiceConfigAndBalancer (cc .dopts .defaultServiceConfig , & defaultConfigSelector {cc .dopts .defaultServiceConfig })
716718 } else {
717- cc .applyServiceConfigAndBalancer (emptyServiceConfig , & defaultConfigSelector {emptyServiceConfig }, addrs )
719+ cc .applyServiceConfigAndBalancer (emptyServiceConfig , & defaultConfigSelector {emptyServiceConfig })
718720 }
719721}
720722
@@ -732,7 +734,7 @@ func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error)
732734 // May need to apply the initial service config in case the resolver
733735 // doesn't support service configs, or doesn't provide a service config
734736 // with the new addresses.
735- cc .maybeApplyDefaultServiceConfig (nil )
737+ cc .maybeApplyDefaultServiceConfig ()
736738
737739 cc .balancerWrapper .resolverError (err )
738740
@@ -744,9 +746,9 @@ func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error)
744746 var ret error
745747 if cc .dopts .disableServiceConfig {
746748 channelz .Infof (logger , cc .channelz , "ignoring service config from resolver (%v) and applying the default because service config is disabled" , s .ServiceConfig )
747- cc .maybeApplyDefaultServiceConfig (s . Addresses )
749+ cc .maybeApplyDefaultServiceConfig ()
748750 } else if s .ServiceConfig == nil {
749- cc .maybeApplyDefaultServiceConfig (s . Addresses )
751+ cc .maybeApplyDefaultServiceConfig ()
750752 // TODO: do we need to apply a failing LB policy if there is no
751753 // default, per the error handling design?
752754 } else {
@@ -759,7 +761,7 @@ func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error)
759761 } else {
760762 configSelector = & defaultConfigSelector {sc }
761763 }
762- cc .applyServiceConfigAndBalancer (sc , configSelector , s . Addresses )
764+ cc .applyServiceConfigAndBalancer (sc , configSelector )
763765 } else {
764766 ret = balancer .ErrBadResolverState
765767 if cc .sc == nil {
@@ -867,15 +869,15 @@ func (cc *ClientConn) removeAddrConn(ac *addrConn, err error) {
867869}
868870
869871// Target returns the target string of the ClientConn.
870- //
871- // # Experimental
872- //
873- // Notice: This API is EXPERIMENTAL and may be changed or removed in a
874- // later release.
875872func (cc * ClientConn ) Target () string {
876873 return cc .target
877874}
878875
876+ // CanonicalTarget returns the canonical target string of the ClientConn.
877+ func (cc * ClientConn ) CanonicalTarget () string {
878+ return cc .parsedTarget .String ()
879+ }
880+
879881func (cc * ClientConn ) incrCallsStarted () {
880882 cc .channelz .ChannelMetrics .CallsStarted .Add (1 )
881883 cc .channelz .ChannelMetrics .LastCallStartedTimestamp .Store (time .Now ().UnixNano ())
@@ -1050,7 +1052,7 @@ func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method st
10501052 })
10511053}
10521054
1053- func (cc * ClientConn ) applyServiceConfigAndBalancer (sc * ServiceConfig , configSelector iresolver.ConfigSelector , addrs []resolver. Address ) {
1055+ func (cc * ClientConn ) applyServiceConfigAndBalancer (sc * ServiceConfig , configSelector iresolver.ConfigSelector ) {
10541056 if sc == nil {
10551057 // should never reach here.
10561058 return
@@ -1694,8 +1696,13 @@ func (cc *ClientConn) parseTargetAndFindResolver() error {
16941696 // We are here because the user's dial target did not contain a scheme or
16951697 // specified an unregistered scheme. We should fallback to the default
16961698 // scheme, except when a custom dialer is specified in which case, we should
1697- // always use passthrough scheme.
1698- defScheme := resolver .GetDefaultScheme ()
1699+ // always use passthrough scheme. For either case, we need to respect any overridden
1700+ // global defaults set by the user.
1701+ defScheme := cc .dopts .defaultScheme
1702+ if internal .UserSetDefaultScheme {
1703+ defScheme = resolver .GetDefaultScheme ()
1704+ }
1705+
16991706 channelz .Infof (logger , cc .channelz , "fallback to scheme %q" , defScheme )
17001707 canonicalTarget := defScheme + ":///" + cc .target
17011708
@@ -1726,6 +1733,8 @@ func parseTarget(target string) (resolver.Target, error) {
17261733 return resolver.Target {URL : * u }, nil
17271734}
17281735
1736+ // encodeAuthority escapes the authority string based on valid chars defined in
1737+ // https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.
17291738func encodeAuthority (authority string ) string {
17301739 const upperhex = "0123456789ABCDEF"
17311740
0 commit comments