@@ -38,6 +38,7 @@ import (
38
38
"google.golang.org/grpc/internal/channelz"
39
39
"google.golang.org/grpc/internal/grpcsync"
40
40
"google.golang.org/grpc/internal/grpcutil"
41
+ iresolver "google.golang.org/grpc/internal/resolver"
41
42
"google.golang.org/grpc/internal/transport"
42
43
"google.golang.org/grpc/keepalive"
43
44
"google.golang.org/grpc/resolver"
@@ -104,6 +105,17 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
104
105
return DialContext (context .Background (), target , opts ... )
105
106
}
106
107
108
+ type defaultConfigSelector struct {
109
+ sc * ServiceConfig
110
+ }
111
+
112
+ func (dcs * defaultConfigSelector ) SelectConfig (rpcInfo iresolver.RPCInfo ) * iresolver.RPCConfig {
113
+ return & iresolver.RPCConfig {
114
+ Context : rpcInfo .Context ,
115
+ MethodConfig : getMethodConfig (dcs .sc , rpcInfo .Method ),
116
+ }
117
+ }
118
+
107
119
// DialContext creates a client connection to the given target. By default, it's
108
120
// a non-blocking dial (the function won't wait for connections to be
109
121
// established, and connecting happens in the background). To make it a blocking
@@ -224,6 +236,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
224
236
case sc , ok := <- cc .dopts .scChan :
225
237
if ok {
226
238
cc .sc = & sc
239
+ cc .safeConfigSelector .UpdateConfigSelector (& defaultConfigSelector {& sc })
227
240
scSet = true
228
241
}
229
242
default :
@@ -273,6 +286,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
273
286
case sc , ok := <- cc .dopts .scChan :
274
287
if ok {
275
288
cc .sc = & sc
289
+ cc .safeConfigSelector .UpdateConfigSelector (& defaultConfigSelector {& sc })
276
290
}
277
291
case <- ctx .Done ():
278
292
return nil , ctx .Err ()
@@ -479,6 +493,8 @@ type ClientConn struct {
479
493
balancerBuildOpts balancer.BuildOptions
480
494
blockingpicker * pickerWrapper
481
495
496
+ safeConfigSelector iresolver.SafeConfigSelector
497
+
482
498
mu sync.RWMutex
483
499
resolverWrapper * ccResolverWrapper
484
500
sc * ServiceConfig
@@ -539,6 +555,7 @@ func (cc *ClientConn) scWatcher() {
539
555
// TODO: load balance policy runtime change is ignored.
540
556
// We may revisit this decision in the future.
541
557
cc .sc = & sc
558
+ cc .safeConfigSelector .UpdateConfigSelector (& defaultConfigSelector {& sc })
542
559
cc .mu .Unlock ()
543
560
case <- cc .ctx .Done ():
544
561
return
@@ -577,13 +594,13 @@ func init() {
577
594
578
595
func (cc * ClientConn ) maybeApplyDefaultServiceConfig (addrs []resolver.Address ) {
579
596
if cc .sc != nil {
580
- cc .applyServiceConfigAndBalancer (cc .sc , addrs )
597
+ cc .applyServiceConfigAndBalancer (cc .sc , nil , addrs )
581
598
return
582
599
}
583
600
if cc .dopts .defaultServiceConfig != nil {
584
- cc .applyServiceConfigAndBalancer (cc .dopts .defaultServiceConfig , addrs )
601
+ cc .applyServiceConfigAndBalancer (cc .dopts .defaultServiceConfig , & defaultConfigSelector { cc . dopts . defaultServiceConfig }, addrs )
585
602
} else {
586
- cc .applyServiceConfigAndBalancer (emptyServiceConfig , addrs )
603
+ cc .applyServiceConfigAndBalancer (emptyServiceConfig , & defaultConfigSelector { emptyServiceConfig }, addrs )
587
604
}
588
605
}
589
606
@@ -620,7 +637,15 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
620
637
// default, per the error handling design?
621
638
} else {
622
639
if sc , ok := s .ServiceConfig .Config .(* ServiceConfig ); s .ServiceConfig .Err == nil && ok {
623
- cc .applyServiceConfigAndBalancer (sc , s .Addresses )
640
+ configSelector := iresolver .GetConfigSelector (s )
641
+ if configSelector != nil {
642
+ if len (s .ServiceConfig .Config .(* ServiceConfig ).Methods ) != 0 {
643
+ channelz .Infof (logger , cc .channelzID , "method configs in service config will be ignored due to presence of config selector" )
644
+ }
645
+ } else {
646
+ configSelector = & defaultConfigSelector {sc }
647
+ }
648
+ cc .applyServiceConfigAndBalancer (sc , configSelector , s .Addresses )
624
649
} else {
625
650
ret = balancer .ErrBadResolverState
626
651
if cc .balancerWrapper == nil {
@@ -630,6 +655,7 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
630
655
} else {
631
656
err = status .Errorf (codes .Unavailable , "illegal service config type: %T" , s .ServiceConfig .Config )
632
657
}
658
+ cc .safeConfigSelector .UpdateConfigSelector (& defaultConfigSelector {cc .sc })
633
659
cc .blockingpicker .updatePicker (base .NewErrPicker (err ))
634
660
cc .csMgr .updateState (connectivity .TransientFailure )
635
661
cc .mu .Unlock ()
@@ -864,6 +890,20 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool {
864
890
return curAddrFound
865
891
}
866
892
893
+ func getMethodConfig (sc * ServiceConfig , method string ) MethodConfig {
894
+ if sc == nil {
895
+ return MethodConfig {}
896
+ }
897
+ if m , ok := sc .Methods [method ]; ok {
898
+ return m
899
+ }
900
+ i := strings .LastIndex (method , "/" )
901
+ if m , ok := sc .Methods [method [:i + 1 ]]; ok {
902
+ return m
903
+ }
904
+ return sc .Methods ["" ]
905
+ }
906
+
867
907
// GetMethodConfig gets the method config of the input method.
868
908
// If there's an exact match for input method (i.e. /service/method), we return
869
909
// the corresponding MethodConfig.
@@ -876,17 +916,7 @@ func (cc *ClientConn) GetMethodConfig(method string) MethodConfig {
876
916
// TODO: Avoid the locking here.
877
917
cc .mu .RLock ()
878
918
defer cc .mu .RUnlock ()
879
- if cc .sc == nil {
880
- return MethodConfig {}
881
- }
882
- if m , ok := cc .sc .Methods [method ]; ok {
883
- return m
884
- }
885
- i := strings .LastIndex (method , "/" )
886
- if m , ok := cc .sc .Methods [method [:i + 1 ]]; ok {
887
- return m
888
- }
889
- return cc .sc .Methods ["" ]
919
+ return getMethodConfig (cc .sc , method )
890
920
}
891
921
892
922
func (cc * ClientConn ) healthCheckConfig () * healthCheckConfig {
@@ -909,12 +939,15 @@ func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method st
909
939
return t , done , nil
910
940
}
911
941
912
- func (cc * ClientConn ) applyServiceConfigAndBalancer (sc * ServiceConfig , addrs []resolver.Address ) {
942
+ func (cc * ClientConn ) applyServiceConfigAndBalancer (sc * ServiceConfig , configSelector iresolver. ConfigSelector , addrs []resolver.Address ) {
913
943
if sc == nil {
914
944
// should never reach here.
915
945
return
916
946
}
917
947
cc .sc = sc
948
+ if configSelector != nil {
949
+ cc .safeConfigSelector .UpdateConfigSelector (configSelector )
950
+ }
918
951
919
952
if cc .sc .retryThrottling != nil {
920
953
newThrottler := & retryThrottler {
0 commit comments