func()

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)
}