in client/action.go [100:176]
func (refOpts *ReferenceOptions) refer(srv common.RPCService, info *ClientInfo) {
ref := refOpts.Reference
con := refOpts.Consumer
var methods []string
if info != nil {
ref.InterfaceName = info.InterfaceName
methods = info.MethodNames
refOpts.id = info.InterfaceName
refOpts.info = info
} else if srv != nil {
refOpts.id = common.GetReference(srv)
} else {
refOpts.id = ref.InterfaceName
}
// If adaptive service is enabled,
// the cluster and load balance should be overridden to "adaptivesvc" and "p2c" respectively.
if con != nil && con.AdaptiveService {
ref.Cluster = constant.ClusterKeyAdaptiveService
ref.Loadbalance = constant.LoadBalanceKeyP2C
}
// cfgURL is an interface-level invoker url, in the other words, it represents an interface.
cfgURL := common.NewURLWithOptions(
common.WithPath(ref.InterfaceName),
common.WithProtocol(ref.Protocol),
common.WithMethods(methods),
common.WithParams(refOpts.getURLMap()),
common.WithParamsValue(constant.BeanNameKey, refOpts.id),
common.WithParamsValue(constant.MetadataTypeKey, refOpts.metaDataType),
common.WithParamsValue(constant.TimeoutKey, refOpts.Consumer.RequestTimeout),
common.WithParamsValue(constant.KeepAliveInterval, ref.KeepAliveInterval),
common.WithParamsValue(constant.KeepAliveTimeout, ref.KeepAliveTimeout),
)
if info != nil {
cfgURL.SetAttribute(constant.ClientInfoKey, info)
}
if ref.ForceTag {
cfgURL.AddParam(constant.ForceUseTag, "true")
}
refOpts.postProcessConfig(cfgURL)
// if mesh-enabled is set
updateOrCreateMeshURL(refOpts)
// retrieving urls from config, and appending the urls to refOpts.urls
urls, err := processURL(ref, refOpts.registriesCompat, cfgURL)
if err != nil {
panic(err)
}
// build invoker according to urls
invoker, err := buildInvoker(urls, ref)
if err != nil {
panic(err)
}
refOpts.urls = urls
refOpts.invoker = invoker
// create proxy
if info == nil && srv != nil {
if ref.Async {
var callback common.CallbackResponse
if asyncSrv, ok := srv.(common.AsyncCallbackService); ok {
callback = asyncSrv.CallBack
}
refOpts.pxy = extension.GetProxyFactory(con.ProxyFactory).GetAsyncProxy(refOpts.invoker, callback, cfgURL)
} else {
refOpts.pxy = extension.GetProxyFactory(con.ProxyFactory).GetProxy(refOpts.invoker, cfgURL)
}
refOpts.pxy.Implement(srv)
}
// this protocol would be destroyed in graceful_shutdown
// please refer to (https://github.com/apache/dubbo-go/issues/2429)
graceful_shutdown.RegisterProtocol(ref.Protocol)
}