@@ -152,6 +152,16 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
152
152
for _ , opt := range opts {
153
153
opt .apply (& cc .dopts )
154
154
}
155
+
156
+ // Determine the resolver to use.
157
+ if err := cc .initParsedTargetAndResolverBuilder (); err != nil {
158
+ return nil , err
159
+ }
160
+
161
+ for _ , opt := range globalPerTargetDialOptions {
162
+ opt .DialOptionForTarget (cc .parsedTarget .URL ).apply (& cc .dopts )
163
+ }
164
+
155
165
chainUnaryClientInterceptors (cc )
156
166
chainStreamClientInterceptors (cc )
157
167
@@ -168,25 +178,16 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
168
178
}
169
179
cc .mkp = cc .dopts .copts .KeepaliveParams
170
180
171
- // Register ClientConn with channelz.
172
- cc .channelzRegistration (target )
173
-
174
- // TODO: Ideally it should be impossible to error from this function after
175
- // channelz registration. This will require removing some channelz logs
176
- // from the following functions that can error. Errors can be returned to
177
- // the user, and successful logs can be emitted here, after the checks have
178
- // passed and channelz is subsequently registered.
179
-
180
- // Determine the resolver to use.
181
- if err := cc .parseTargetAndFindResolver (); err != nil {
182
- channelz .RemoveEntry (cc .channelz .ID )
183
- return nil , err
184
- }
185
- if err = cc .determineAuthority (); err != nil {
186
- channelz .RemoveEntry (cc .channelz .ID )
181
+ if err = cc .initAuthority (); err != nil {
187
182
return nil , err
188
183
}
189
184
185
+ // Register ClientConn with channelz. Note that this is only done after
186
+ // channel creation cannot fail.
187
+ cc .channelzRegistration (target )
188
+ channelz .Infof (logger , cc .channelz , "parsed dial target is: %#v" , cc .parsedTarget )
189
+ channelz .Infof (logger , cc .channelz , "Channel authority set to %q" , cc .authority )
190
+
190
191
cc .csMgr = newConnectivityStateManager (cc .ctx , cc .channelz )
191
192
cc .pickerWrapper = newPickerWrapper (cc .dopts .copts .StatsHandlers )
192
193
@@ -587,11 +588,11 @@ type ClientConn struct {
587
588
588
589
// The following are initialized at dial time, and are read-only after that.
589
590
target string // User's dial target.
590
- parsedTarget resolver.Target // See parseTargetAndFindResolver ().
591
- authority string // See determineAuthority ().
591
+ parsedTarget resolver.Target // See initParsedTargetAndResolverBuilder ().
592
+ authority string // See initAuthority ().
592
593
dopts dialOptions // Default and user specified dial options.
593
594
channelz * channelz.Channel // Channelz object.
594
- resolverBuilder resolver.Builder // See parseTargetAndFindResolver ().
595
+ resolverBuilder resolver.Builder // See initParsedTargetAndResolverBuilder ().
595
596
idlenessMgr * idle.Manager
596
597
597
598
// The following provide their own synchronization, and therefore don't
@@ -1673,22 +1674,19 @@ func (cc *ClientConn) connectionError() error {
1673
1674
return cc .lastConnectionError
1674
1675
}
1675
1676
1676
- // parseTargetAndFindResolver parses the user's dial target and stores the
1677
- // parsed target in `cc.parsedTarget`.
1677
+ // initParsedTargetAndResolverBuilder parses the user's dial target and stores
1678
+ // the parsed target in `cc.parsedTarget`.
1678
1679
//
1679
1680
// The resolver to use is determined based on the scheme in the parsed target
1680
1681
// and the same is stored in `cc.resolverBuilder`.
1681
1682
//
1682
1683
// Doesn't grab cc.mu as this method is expected to be called only at Dial time.
1683
- func (cc * ClientConn ) parseTargetAndFindResolver () error {
1684
- channelz .Infof (logger , cc . channelz , "original dial target is: %q" , cc .target )
1684
+ func (cc * ClientConn ) initParsedTargetAndResolverBuilder () error {
1685
+ logger .Infof ("original dial target is: %q" , cc .target )
1685
1686
1686
1687
var rb resolver.Builder
1687
1688
parsedTarget , err := parseTarget (cc .target )
1688
- if err != nil {
1689
- channelz .Infof (logger , cc .channelz , "dial target %q parse failed: %v" , cc .target , err )
1690
- } else {
1691
- channelz .Infof (logger , cc .channelz , "parsed dial target is: %#v" , parsedTarget )
1689
+ if err == nil {
1692
1690
rb = cc .getResolver (parsedTarget .URL .Scheme )
1693
1691
if rb != nil {
1694
1692
cc .parsedTarget = parsedTarget
@@ -1707,15 +1705,12 @@ func (cc *ClientConn) parseTargetAndFindResolver() error {
1707
1705
defScheme = resolver .GetDefaultScheme ()
1708
1706
}
1709
1707
1710
- channelz .Infof (logger , cc .channelz , "fallback to scheme %q" , defScheme )
1711
1708
canonicalTarget := defScheme + ":///" + cc .target
1712
1709
1713
1710
parsedTarget , err = parseTarget (canonicalTarget )
1714
1711
if err != nil {
1715
- channelz .Infof (logger , cc .channelz , "dial target %q parse failed: %v" , canonicalTarget , err )
1716
1712
return err
1717
1713
}
1718
- channelz .Infof (logger , cc .channelz , "parsed dial target is: %+v" , parsedTarget )
1719
1714
rb = cc .getResolver (parsedTarget .URL .Scheme )
1720
1715
if rb == nil {
1721
1716
return fmt .Errorf ("could not get resolver for default scheme: %q" , parsedTarget .URL .Scheme )
@@ -1805,7 +1800,7 @@ func encodeAuthority(authority string) string {
1805
1800
// credentials do not match the authority configured through the dial option.
1806
1801
//
1807
1802
// Doesn't grab cc.mu as this method is expected to be called only at Dial time.
1808
- func (cc * ClientConn ) determineAuthority () error {
1803
+ func (cc * ClientConn ) initAuthority () error {
1809
1804
dopts := cc .dopts
1810
1805
// Historically, we had two options for users to specify the serverName or
1811
1806
// authority for a channel. One was through the transport credentials
@@ -1838,6 +1833,5 @@ func (cc *ClientConn) determineAuthority() error {
1838
1833
} else {
1839
1834
cc .authority = encodeAuthority (endpoint )
1840
1835
}
1841
- channelz .Infof (logger , cc .channelz , "Channel authority set to %q" , cc .authority )
1842
1836
return nil
1843
1837
}
0 commit comments