vipyxc-byte commented on issue #2981:
URL: https://github.com/apache/dubbo-go/issues/2981#issuecomment-3212917787

   rpc服务加载代码:
   
   `func (r *reference) load(api *GenericApi, trace logger.Logger) 
(common.RPCService, error) {
        r.lock.Lock()
        defer r.lock.Unlock()
        refId := api.RefId()
   
        if r.rf != nil {
                return r.rf.GetRPCService(), nil
        }
   
        if api.protocol == "" {
                api.protocol = constant.Dubbo
        }
   
        if api.timeout == "" {
                api.timeout = t.Consumer.RequestTimeout
        }
   
        if api.retries == "" {
                api.retries = "0"
        }
   
        r.rf = config.NewReferenceConfigBuilder().
                SetInterface(api.interfaceName).
                SetGroup(api.group).
                SetVersion(api.version).
                SetRequestTimeout(api.timeout).
                SetRetries(api.retries).
                SetProtocol(api.protocol).
                SetRegistryIDs(t.Consumer.RegistryIDs...).
                SetGeneric(true).
                SetSerialization(constant.Hessian2Serialization).
                SetLoadbalance(constant.LoadBalanceKeyRandom).
                SetCluster(constant.ClusterKeyFailover).
                Build()
        rootConfig := config.GetRootConfig()
        err := r.rf.Init(rootConfig)
        if err != nil {
                return nil, err
        }
   
        // v3.2.0-rc1 refConf.GenericLoad(refId)存在bug,需要手动创建和关联相关的GenericService
        // v3.3.0 修复了这个bug,直接使用refConf.GenericLoad(refId)即可
        // refConf.GenericLoad(refId)
        // 自维护,所以手动创建和关联GenericService,而且不需要 onfig.SetConsumerService(gs)
        gs := generic.NewGenericService(refId)
        r.rf.Refer(gs)
        r.rf.Implement(gs)
        // config.SetConsumerService(gs)
   
        waitTime := api.waitForInitSecond
        if waitTime <= 0 {
                waitTime = 5 * time.Second
        }
   
        timeout, cancel := context.WithTimeout(context.Background(), waitTime)
        defer cancel()
        index := 0
   end:
        for {
                index++
                select {
                case <-timeout.Done():
                        trace.Warn("dubbo rpc service load timeout")
                        break end
                default:
                        b := r.recheck(r.rf.GetInvoker(), trace)
                        if b {
                                trace.Infof("dubbo rpc service load success, 
recheck count: %d", index)
                                break end
                        }
                        time.Sleep(1 * time.Second)
                }
        }
        return r.rf.GetRPCService(), nil
   }
   
   // recheck 检查invoker是否可用
   func (r *reference) recheck(invoker protocol.Invoker, trace logger.Logger) 
bool {
        defer func() {
                // invoker.IsAvailable 逻辑中可能会有 panic: runtime error: invalid 
memory address or nil pointer dereference
                if r := recover(); r != nil {
                        trace.Info("generic service not ready, wait for next 
check")
                }
        }()
        if !invoker.IsAvailable() {
                return false
        }
        return true
   }`


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to